Javascript Node Js将文件交付给客户端
当您将Javascript Node Js将文件交付给客户端,javascript,node.js,Javascript,Node.js,当您将HTML文件发送到客户端时,它会被解析并发出GET调用,以调用任何其他内容,如或(其中是否包含,我想是的) 执行此过程非常昂贵: 请求文件-客户端 从磁盘读取文件-节点 将内容发布到响应流-节点 读取响应流-客户端 当服务器启动时,是否仍要在节点中缓存文件内容,以便简单地执行此操作 请求文件-客户端 将内容发布到响应流-节点 读取响应流-客户端 我有这个功能,可以浏览scripts/文件夹中的所有脚本并读取文件: var gatherFiles = function () {
HTML
文件发送到客户端时,它会被解析并发出GET
调用,以调用任何其他内容,如
或
(其中是否包含
,我想是的)
执行此过程非常昂贵:
- 请求文件-客户端
- 从磁盘读取文件-节点
- 将内容发布到响应流-节点
- 读取响应流-客户端
- 请求文件-客户端
- 将内容发布到响应流-节点
- 读取响应流-客户端
scripts/
文件夹中的所有脚本并读取文件:
var gatherFiles = function () {
fs.readdir('/Scripts', function (err, files) {
files.filter(function (file) {
return path.extname(file) == '.js';
}).forEach(function (file) {
// read files here
});
});
};
牢记这些要点
- 它在一个树莓圆周率,它不需要是可伸缩的
- 我不介意一开始是不是很贵
100Kb
max(缩小后可能要小得多)
我问这个问题,因为当我做了Chrome
和Firefox
网络监视器来查看提供文件需要多长时间,而且需要很长时间,超过100ms
我猜服务器的许多部分都存在延迟:以太网、SD卡、代码
因此,我认为我想用预缓存的方式来实现,它应该最小化100ms
延迟
*我的解决方案*
var fs = require ("fs"),
path = require("path"),
async = require("async"),
scriptFiles = {};
function gatherFiles(callback, folder) {
fs.readdir(folder, function (err, files) {
var filteredFiles = files.filter(function (file) {
var ext = path.extname(file);
return ext == '.js' || ext == '.html';
});
aync.each(filteredFiles, function (file, asynCallback) {
if (!scriptFiles[file])
fs.readFile(folder + '/' + file, function (err, data) {
scriptFiles[file] = data;
asyncCallback();
});
}, function (err) {
callback(scriptFiles);
});
});
};
exports.gatherFiles = gatherFiles;
需要注意的要点是:
- Async-each要求您启动一个回调,让它知道函数已完成,当它检测到所有回调已启动时,它将调用最终回调,这也允许允许错误通过
- 在最后一次回调中,它调用主函数回调并通过文件字典传递数据,然后匿名函数应该启动http服务器
var cacher = require("./cacher");
cacher.gatherFiles(function (fileDictionary) {
http.createServer(onRequest, 8888);
}, './Scripts');
我认为这样的东西会满足您的要求,即试图消除磁盘读取
function Files = function () {
var files = {};
return function (filepath, callback) {
// If cache is available, return that
if (files[filepath]) return callback(null, files[filepath]);
// Otherwise, get it, then store it
fs.readFile(filepath, function (err, data) {
if (err) return callback(err);
files[filepath] = data;
callback(null, data);
});
}
}();
那么就这样称呼它吧
Files('/scripts/whatever.js', function (err, data) {
// Do something
});
如果愿意,可以添加其他功能,如文件监视或缓存过期
如果您想在开始时缓存所有内容,您可以迭代任何目录,而不使用回调
为此,我将对其进行如下修改:
//...
if (files[filepath]) return callback && callback(null, files[filepath]);
//...
callback && callback(null, data);
//...
callback&&callback(…)
将被视为与if(false&&alert(“Nothing”)
相同,因为falsy条件会阻止进一步执行,因此警报永远不会到达。因此,如果您不传递回调,它将永远不会尝试执行回调。有点像故障保护。只要确保添加了正确的标题,静态文件就会被浏览器缓存。@adeneo我想No1_Melman希望将文件缓存在服务器端(而不是浏览器),以避免多次读取文件。@san.chez-我明白了,我就是不明白why@adeneo这是因为每次从服务器调用它们都很昂贵。事实并非如此,Node可以毫无问题地处理数百万个静态资源请求,而且考虑到静态资源只在第一次由浏览器请求,因为它们应该在下次缓存,这是你拥有的最便宜的东西之一。另外,比较一下大多数用户的磁盘读取速度、内存速度和网络速度,想想什么时间最长。朋友,这是一个很好的答案,非常感谢您花费的时间和精力:)@No1_Melman请告诉我们结果。它将100ms的延迟减少了多少?@san.chez,我现在正在实施,将在bitCurrent Stats Ares(旧实施)中发回结果。但是,发送和接收文件所需的时间少于40ms
,实际调用脚本文件需要103ms
。@san.chez在预缓存文件时有一个200ms
保存,我将在我的答案中发布一个编辑,说明我是如何做的