Web Workers - JSON的可转换对象

时间:2012-07-06 16:09:35

标签: javascript json html5 web-worker

HTML 5在大型JSON对象上使用worker.postMessage时,Web worker非常慢。 我正在尝试弄清楚如何将JSON对象传输给Web工作者 - 使用Chrome中的'Transferable Objects'类型,以提高速度。

这就是我所指的并且似乎应该加快这一点: http://updates.html5rocks.com/2011/12/Transferable-Objects-Lightning-Fast

我很难找到一个很好的例子(我不相信我想使用ArrayBuffer)。任何帮助将不胜感激。

我正在想象这样的事情:

worker = new Worker('workers.js');

var large_json = {};
for(var i = 0; i < 20000; ++i){
   large_json[i] = i;
   large_json["test" + i] = "string";
};

//How to make this call to use Transfer Objects? Takes approx 2 seconds to serialize this for me currently.
worker.webkitPostMessage(large_json);

3 个答案:

答案 0 :(得分:2)

如果你必须从现有的Json数组(从非常接近于克隆......)开始构建它,那么使用transferable对象将无济于事。

Json数据来自哪里?在工作线程上保留所有辛苦工作的一种可能方法是让它使用XmlHttpRequest获取数据,转换它并将其发送到UI线程。这样,克隆的高成本发生在工作线程上,虽然它将花费与UI线程相同的时间,但它不会阻止您的应用程序。

答案 1 :(得分:0)

虽然没有使用'Transferable Objects',但这可以解决您的问题。

您也可以尝试优化数据表示。 例如。您的示例需要大约1350毫秒来打包/解压缩(Google Chrome 19),但执行以下代码〜快25倍(50毫秒):

console.time('json');
var a = [], test = [];
for(var i = 0; i < 20000; ++i){
   a.push(i);
   test.push("string");
};
var large_json = {
  a: a.join(','),
  test: test.join(',')
};
large_json = JSON.parse(JSON.stringify(large_json));
large_json.a = large_json.a.split(",");
large_json.test = large_json.test.split(",");
console.timeEnd('json');

答案 2 :(得分:0)

好的,我做了这个,我不知道它是好还是坏,理想或最糟糕的方式来做到这一点。我刚刚做完。 在工作文件中

var data = e.data;
var string = String.fromCharCode.apply(null, new Uint16Array(data));
var objnow = JSON.parse(string);

在html文件中

function str2ab(str) {
   var buf = new ArrayBuffer(str.length*2); // 2 bytes for each char
   var bufView = new Uint16Array(buf);
   for (var i=0, strLen=str.length; i<strLen; i++) {
     bufView[i] = str.charCodeAt(i);
   }
   return buf;
 }
function stop() {
 var obj = {'cmd': 'stop', 'msg': 'Bye'};
 var str= JSON.stringify(obj);
 var arbfr = str2ab(obj);
 worker.postMessage(arbfr,[arbfr]);
}

现在它可以工作,我可以发送json对象,传输。