我正在编写一个Chrome扩展程序,它可以在浏览器的localStorage中存储大量数据,并在每次加载页面时对其进行解析。现在随着数据大小的增加,页面加载时间/性能开始降低。所以我想把解析委托给一个web worker。但我怀疑它是否值得。我能做的就是把我的字符串传递给像这样的工人。
worker.postMessage(localStorage['myObj']);
我计划将此字符串解析为JSON并将其发送回主线程,如此
worker.onMessage(function(myObj){
//Then Play around with my object here.
});
但是当我搜索这种方法的性能方面时,包括消息发布和监听开销,以及某些浏览器不允许在消息中发送JSON对象并且一些自动序列化的事实发送,我怀疑这种方法是否值得。
由于我的应用只是Chrome扩展程序和Firefox插件,我只关注这两种浏览器。如果这种方法适用于这两种浏览器,有人可以建议我吗?
答案 0 :(得分:10)
目前接受的答案完全不正确。完成你所问的事情是完全可行的,例如下面的例子。
它是否值得这样做是您必须检查真实场景中的真实数据。将JSON文本发送给工作者并让它发送回解析结果(这可能涉及一些不完整的序列化,尽管它可能不是JSON)和现代浏览器相关的开销很快解析JSON。
我怀疑开销是不值得的,但是如果浏览器的本机序列化机制比JSON快得多或者发生在主UI线程以外的线程上,那么可能是巨大的JSON字符串也许它可能是。
使用worker解析JSON的示例:
// This stands in for 'worker.js':
var blob = new Blob([
'this.onmessage = function(message) {\n' +
'postMessage(JSON.parse(message.data));\n' +
'};'
], { type: "text/javascript" });
var workerUrl = URL.createObjectURL(blob);
// Main script:
var w = new Worker(workerUrl/*"worker.js"*/);
w.onmessage = function(message) {
display("Got response: typeof message.data: " + typeof message.data);
display("message.data.for = " + message.data.foo);
};
display('Posting JSON \'{"foo":"bar"}\' to worker');
w.postMessage('{"foo":"bar"}');
function display(msg) {
var p = document.createElement('p');
p.innerHTML = String(msg);
document.body.appendChild(p);
}

body {
font-family: monospace;
}

结果:
Posting JSON '{"foo":"bar"}' to worker Got response: typeof message.data: object message.data.for = bar
答案 1 :(得分:1)
只能在WebWorkers之间传递字符串,而不是对象。如果将字符串解析为WebWorker中的JSON对象,则需要对该对象进行字符串化,然后在将该对象从工作程序传递到主脚本时对其进行重新分析。显然,这会导致不必要地对JSON进行双重解析,因此这是一个坏主意。
2017年更新:现在不仅仅是字符串了。查看一些(更新的)答案和评论以供参考。