【问题标题】:Javascript Webworker postmessage is really slow even with short string messages即使是短字符串消息,Javascript Webworker postmessage 也很慢
【发布时间】:2020-02-28 17:13:37
【问题描述】:

我正在尝试使用 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;
});

立即在 webworker 中的 onmessage 中记录时间

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

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

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

【问题讨论】:

    标签: javascript web-worker postmessage


    【解决方案1】:

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

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

    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 框架。

    【讨论】:

      猜你喜欢
      • 2014-08-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-20
      • 1970-01-01
      • 1970-01-01
      • 2012-11-10
      • 1970-01-01
      相关资源
      最近更新 更多