Javascript 让网络工作者更快、毫不拖延地开始工作
我正试图加快一个javascript网站的速度,我正在和一个网络工作者一起构建这个网站。这对我来说是全新的,我正在学习 我设法让这个web worker运行并执行它应该执行的操作(即加载一些CSV数据,转换并发送回) 但在我看来,这个网络工作者开始工作有点太晚了(在我给他发邮件500毫秒后) 这正常吗?Javascript 让网络工作者更快、毫不拖延地开始工作,javascript,multithreading,performance,web-worker,Javascript,Multithreading,Performance,Web Worker,我正试图加快一个javascript网站的速度,我正在和一个网络工作者一起构建这个网站。这对我来说是全新的,我正在学习 我设法让这个web worker运行并执行它应该执行的操作(即加载一些CSV数据,转换并发送回) 但在我看来,这个网络工作者开始工作有点太晚了(在我给他发邮件500毫秒后) 这正常吗? 为什么工人不早点开始工作? 我能做什么 这是工人: self.postMessage('A. !!! Worker on'); self.onmessage = function(event)
为什么工人不早点开始工作?
我能做什么 这是工人:
self.postMessage('A. !!! Worker on');
self.onmessage = function(event) {
var n=event.data;
self.postMessage('['+n+'] B. Worker started');
// (...)
}
window.timer = Date.now();
window.timerTotal = window.timer;
function loadData(n){
console.log('A. !!! Begin loadData function (dt=' + (Date.now()-window.timer) + ') (T='+(Date.now()-window.timerTotal)+')'); window.timer = Date.now();
var worker = new Worker('my_task.js');
worker.onmessage = function(event) {
if ( (typeof event.data)==='string'){
console.log('Web Worker: ' + event.data + ' (dt=' + (Date.now()-window.timer) + ') (T='+(Date.now()-window.timerTotal)+')'); window.timer = Date.now();
}
else if ( (typeof event.data)==='object'){
console.log('!!! Web Worker returned object: (dt=' + (Date.now()-window.timer) + ') (T='+(Date.now()-window.timerTotal)+')'); window.timer = Date.now();
createGraphs2(event.data);
}
};
if(n===100){
d3.csv("data/Movies100-V2.0.csv", function(error, data_csv) {
createGraphs(data_csv);
});
}
else if(n==='10k'){
worker.postMessage(n);
console.log('postMessage send to web worker (dt=' + (Date.now()-window.timer) + ') (T='+(Date.now()-window.timerTotal)+')'); window.timer = Date.now();
}
}
loadData('10k');
// (...) lots of functions like createGraphs2(data)
以下是对工人的处理:
self.postMessage('A. !!! Worker on');
self.onmessage = function(event) {
var n=event.data;
self.postMessage('['+n+'] B. Worker started');
// (...)
}
window.timer = Date.now();
window.timerTotal = window.timer;
function loadData(n){
console.log('A. !!! Begin loadData function (dt=' + (Date.now()-window.timer) + ') (T='+(Date.now()-window.timerTotal)+')'); window.timer = Date.now();
var worker = new Worker('my_task.js');
worker.onmessage = function(event) {
if ( (typeof event.data)==='string'){
console.log('Web Worker: ' + event.data + ' (dt=' + (Date.now()-window.timer) + ') (T='+(Date.now()-window.timerTotal)+')'); window.timer = Date.now();
}
else if ( (typeof event.data)==='object'){
console.log('!!! Web Worker returned object: (dt=' + (Date.now()-window.timer) + ') (T='+(Date.now()-window.timerTotal)+')'); window.timer = Date.now();
createGraphs2(event.data);
}
};
if(n===100){
d3.csv("data/Movies100-V2.0.csv", function(error, data_csv) {
createGraphs(data_csv);
});
}
else if(n==='10k'){
worker.postMessage(n);
console.log('postMessage send to web worker (dt=' + (Date.now()-window.timer) + ') (T='+(Date.now()-window.timerTotal)+')'); window.timer = Date.now();
}
}
loadData('10k');
// (...) lots of functions like createGraphs2(data)
下面是日志:
开始加载数据功能(dt=7)(T=7)向网络工作者发送postMessage(dt=1)(T=8)
网络工作者:A!!!工作人员(dt=524)(T=591)
Web工作人员:[10k]B.工作人员已启动(dt=1)(T=593) 谢谢 更新: 当我在启动veryLongScript的同时向worker发送postMessage时:
veryLongScript();
worker.postMessage(n);
大多数情况下,工作人员在veryLongScript之后做出响应
(veryLongScript)网络工作者:A!!!工人在(dt=301)(T=12464)
网络工作者:[10k]B.工作者已启动(dt=1)(T=12465)
Web工作者:[10k]C.已加载依赖项(dt=600)(T=13065) 有时,工作人员在veryLongScript之前和之后都会做出响应,但它似乎不是并行工作的 网络工作者:A!!!工作人员(dt=1235)(T=1416)
网络工作者:[10k]B.工作者已启动(dt=0)(T=1418)
(veryLongScript)
Web工作者:[10k]C.已加载依赖项(dt=619)(T=13168)
当您通过创建新的辅助对象时
new Worker('my_task.js');
只有在这一点上,浏览器才会请求服务器让my_task.js
在worker中运行。然后,您正在等待向服务器发出并返回请求,以及正在启动的工作进程
我在上做了一个代码的简化示例。对我来说,Chrome的启动时间大约为130ms。但是,network inspector表示,获取脚本需要约90毫秒的时间。因此,工人的实际启动时间为40ms
我的怀疑是,您报告的500毫秒中的大多数实际上是从服务器获取工作脚本所花费的时间
我的建议是
- 在页面加载时创建工作程序,而不是在您想使用它之前。(虽然如果您已经在页面加载时使用了它,但在这里您可以做的不多)。请参阅,对于我而言,从现有员工处收发消息的时间缩短到~2ms
- 确保浏览器可以缓存Worker javascript文件,并设置适当的HTTP头。因此,除了第一次访问之外,所有访问都避免了网络请求
- 如果有工作者的页面通常不是访问者看到的站点上的第一个页面,那么您可以稍微作弊,将工作者加载到其他页面上,但不使用它。如果脚本具有适当的缓存头,它将避免页面上实际需要它的请求
因此,我会小心地在您想要支持的浏览器上进行测试。谢谢您的回答!我会调查的。你知道
是不必要的吗?在您的示例中变化不大,但可能.html根本不需要获取worker.js?另外,我还有更多信息,将更新该问题。@user456789123我怀疑这是不必要的,可能会导致一些错误,因为它不是在web worker环境中运行的。(假设它试图访问WorkerGlobalScope对象)。