让网络工作者尽快开始,毫不拖延

时间:2015-05-16 11:42:39

标签: javascript multithreading performance web-worker

我正在尝试加速我正在使用网络工作者构建的javascript网站。这对我来说是全新的,我正在学习。

我设法让这个网络工作者运行并做它应该做的事情(即加载一些CSV数据,转换并发送回来)。

但在我看来,这位网络工作者开始他的工作有点太晚了(我发送postMessage后约500毫秒)

这是正常的吗? 为什么工人不能早点开始呢? 我该怎么办?

这是工人:

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)

这是日志:

  

开始loadData函数(dt = 7)(T = 7)
  postMessage发送给web worker(dt = 1)(T = 8)
  网络工作者:A。!!!工人上(dt = 524)(T = 591)
  网络工作者:[10k] B.工人开始(dt = 1)(T = 593)

谢谢!

UPDATE:

当我在启动VeryLongScript的同时向工作人员发送postMessage时:

veryLongScript();
worker.postMessage(n);

大多数情况下,工作人员会在非常长篇大论之后做出回应。

  

(veryLongScript)
  网络工作者:A。!!!工人上(dt = 301)(T = 12464)
  网络工作者:[10k] B.工人开始(dt = 1)(T = 12465)
  Web Worker:[10k] C.依赖加载(dt = 600)(T = 13065)

有时工作人员会在VeryLongScript之前和之后回复一些内容,但它似乎不能并行工作。

  

网络工作者:A。!!!工人上(dt = 1235)(T = 1416)
  网络工作者:[10k] B.工人开始(dt = 0)(T = 1418)
  (veryLongScript)
  Web Worker:加载[10k] C.依赖关系(dt = 619)(T = 13168)

1 个答案:

答案 0 :(得分:2)

创建新工作人员时
new Worker('my_task.js');

仅在此时,浏览器向服务器发出请求以使my_task.js在工作程序中运行。然后,您正在等待对服务器的请求以及正在启动的工作程序。

我在http://plnkr.co/edit/MlabLs4HafnIscBbnPJv?p=preview处制作了代码示例。对我而言,它报告启动工作人员的时间为~130毫秒。但是,网络检查员声明获取脚本需要大约90ms。因此,为工人的实际启动时间留下40ms。

我怀疑你报告的500ms中的大多数实际上是从服务器获取工作者脚本所花费的时间。

我的推荐是

  • 在页面加载时创建工作程序,而不是在您想要使用它之前。 (虽然如果您已经在页面加载时使用它,那么您可以在这里做很多事情)。请参阅http://plnkr.co/edit/cNltJvTbLxDr2FfaCuRf?p=preview,我现有工作人员收到/返回的消息时间可缩短至约2毫秒。

  • 确保浏览器可以缓存Worker javascript文件,并设置适当的HTTP标头。因此,除了第一次访问外,请避免网络请求。

  • 如果带有工作人员的页面通常不是访问者看到的网站上的第一个页面,则可能会略微欺骗并在其他页面上加载工作人员,但不会使用它。如果脚本具有适当的缓存标头,则它将避免页面上实际需要它的请求。

或者,您可以避免将worker作为单独的文件,并将代码内联并将其转换为数据URI,如https://stackoverflow.com/a/6454685/1319998所述。 ,如https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers

所述
  

目前,浏览器供应商对于哪些URI是同源的存在分歧; Gecko 10.0(Firefox 10.0 / Thunderbird 10.0 / SeaMonkey 2.7)及更高版本允许数据URI,Internet Explorer 10不允许Blob URI作为工作人员的有效脚本。

所以我会小心测试你想要支持的浏览器。