我正在尝试加快我与网络 worker 一起构建的 JavaScript 网站的速度。这对我来说是全新的,我正在学习。
我设法让这个网络 worker 运行并做它应该做的事情(即加载一些 CSV 数据,转换它并将其发回)。
但在我看来,这个网络 worker 开始工作有点太晚了(在我向他发送 postMessage 后大约 500 毫秒)
这正常吗?
worker 怎么不早点开始?
我能做什么?
这是 worker :
self.postMessage('A. !!! Worker on');
self.onmessage = function(event) {
var n=event.data;
self.postMessage('['+n+'] B. Worker started');
// (...)
}
这是 worker 的处理:
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)
这是日志:
Begin loadData function (dt=7) (T=7)
postMessage send to web worker (dt=1) (T=8)
Web Worker: A. !!! Worker on (dt=524) (T=591)
Web Worker: [10k] B. Worker started (dt=1) (T=593)
谢谢!
更新:
当我在启动veryLongScript的同时向工作人员发送postMessage时:
veryLongScript();
worker.postMessage(n);
大多数时候,worker 在veryLongScript 之后响应。
(veryLongScript)
Web Worker: A. !!! Worker on (dt=301) (T=12464)
Web Worker: [10k] B. Worker started (dt=1) (T=12465)
Web Worker: [10k] C. dependencies loaded (dt=600) (T=13065)
有时工作人员会在veryLongScript之前和之后响应一些内容,但它似乎不能并行工作。
Web Worker: A. !!! Worker on (dt=1235) (T=1416)
Web Worker: [10k] B. Worker started (dt=0) (T=1418)
(veryLongScript)
Web Worker: [10k] C. dependencies loaded (dt=619) (T=13168)
最佳答案
当你创建一个新的worker时
new Worker('my_task.js');
只有在此时,浏览器才会向服务器发出请求,以获取 my_task.js
在工作线程中运行。然后,您将等待向服务器发出并返回请求,以及启动工作线程。
我在 http://plnkr.co/edit/MlabLs4HafnIscBbnPJv?p=preview 上制作了您的代码的简化示例。对我来说,它报告 Chrome 启动工作线程的时间约为 130 毫秒。然而,网络检查员指出获取脚本大约需要 90 毫秒。这样就为worker的实际启动时间留下了40ms。
我怀疑您报告的 500 毫秒中的大部分实际上是从服务器获取工作脚本所花费的时间。
我的建议是
在页面加载时创建工作线程,而不是在您想要使用它之前创建它。 (尽管如果您在页面加载时已经使用它,那么您在这里无能为力)。请参阅http://plnkr.co/edit/cNltJvTbLxDr2FfaCuRf?p=preview对我来说,从现有工作人员接收消息或从现有工作人员返回消息的时间缩短至约 2 毫秒。
确保 Worker javascript 文件可由浏览器缓存,设置适当的 HTTP header 。因此,除了第一次访问之外,避免所有网络请求。
如果包含工作器的页面通常不是访问者在您网站上看到的第一个页面,您可以稍微作弊并将工作器加载到其他页面上,但不使用它。如果脚本具有适当的缓存 header ,它将避免实际需要它的页面上的请求。
或者,您可以避免将工作线程作为单独的文件,并将代码内联并将其转换为数据 URI,如 https://stackoverflow.com/a/6454685/1319998 中所述。 。 但是如https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers所述
There is currently disagreement among browsers vendors on what URIs are of the same-origin; Gecko 10.0 (Firefox 10.0 / Thunderbird 10.0 / SeaMonkey 2.7) and later do allow data URIs and Internet Explorer 10 does not allow Blob URIs as a valid script for workers.
所以我会小心地在您想要支持的浏览器上进行测试。
关于javascript - 让网络 worker 更快、毫不拖延地开始,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30275218/