首页 > 解决方案 > 即使是短字符串消息,Javascript Webworker postmessage 也很慢

问题描述

我正在尝试使用 postMessage 向网络工作者发送一个字符串。这始终需要> 100毫秒才能完成。这是主线程中的相关代码

return new Promise(function(resolve, reject) {
  let w = new Worker(<webworker_url>)
  w.onmessage = function(e) {
    resolve(e.data);
  }
  console.log(Date.now());
  w.postMessage('test text');
  w.onerror = reject;
});

立即在onmessagewebworker中记录时间

onmessage = function(e) {
   console.log(Date.now());
   ...
}

控制台中显示的时间超过 100 毫秒,将浏览器切换到 chrome dev 或 chrome canary 会有所帮助,但不会超过 50 毫秒,这在我的理解中仍然很慢。

我对 postMessage 速度的理解是错误的吗?还是我的代码错了?

标签: javascriptweb-workerpostmessage

解决方案


问题在于,每次调用该承诺时,您都会创建一个新的 WebWorker。创建 web worker 有很多开销——浏览器需要初始化新的 JS 引擎,解析 javascripts 等。

您需要以某种方式缓存已初始化的工作人员,或将其提供给承诺。然后,您需要创建一个系统来确定哪个消息属于哪个承诺。一些入门的想法:

let _cachedWorker = null;
let _uniqueMessageId = 0;
function _getWorker() {
  if(_cachedWorker == null) {
    _cachedWorker = new Worker(<webworker_url>);
  }
  return _cachedWorker;
}

function WorkerOperationPromise(messageData) {
  return new Promise(function(resolve, reject) {
    let w = _getWorker();
    const currentMessageId = ++_uniqueMessageId;
    w.addEventListener("message", function(e) {
      if(e.data.messageId == currentMessageId) {
        resolve(e.data.messageData);
        // You MUST! also remove this listener somehow
      }
    });
    w.postMessage({messageId: currentMessageId, messageData});
  });
}

或者使用一些已经可以做到这一点的 RPC 框架。


推荐阅读