导入前段时间开发的项目pptx,由于自身代码问题导致性能问题。一个40p的pptx文件转成json数据用了大概60s+,虽然后来发现是使用频率很高的一个。在函数内部,是由于使用了newFunction构造函数造成的(所以这里提醒一下,如果在意几毫秒的差距,建议慎用),但是在优化过程中,它一度怀疑性能达到瓶颈,于是尝试使用webworker进行优化。因为是文件,所以内容一般比较大。发现webworker大部分时间都在传值上,所以想开这篇文章详细说说。两种传值方式关于webworker的基本使用和传值方式网上有很多介绍,这里不再赘述。这里我们重点关注一下,同一个文件,两种方式传值会有多大的区别。随意在这里从计算机上找到一个96MB的PSD文件进行测试。主线程fetch('./case.psd').then(file=>{returnfile.blob();}).then(blob=>{returnnewPromise(resolve=>{letfileReader=newFileReader();fileReader.onload=e=>{resolve(e.target.result);}fileReader.readAsArrayBuffer(blob);})}).then(buf=>{letworker=newWorker('1.js');console.time('计算时间');worker.postMessage(buf);worker.onmessage=e=>{console.timeEnd('计算时间');}})worker(子)线程,这里为了避免不必要的干扰,worker线程什么都不做,收到消息后,直接post一个消息回self.onmessage=e=>{postMessage(0);}这里我直接使用FileReader的readAsArrayBuffer读出一个长度为96,138,230的字符串,大约是9600万,需要70ms左右的值,下同)我们把上面主线程的代码稍微改动一下,使用传输数据的方法-worker.postMessage(buf);+worker.postMessage(buf,[buf]);同样的一条数据大约需要17ms,这个17ms好像是一个固定值。我试图更改一个800MB+的文件和一个空的文本文件,其中没有任何内容。大约是这个时候。不同的数据类型按值传输需要不同的时间。fetch('./case.psd').then(file=>{returnfile.blob();}).then(blob=>{returnnewPromise(resolve=>{letfileReader=newFileReader();fileReader.onload=e=>{resolve(e.target.result);}fileReader.readAsText(blob);})}).then(str=>{console.log(str.length);letworker=newWorker('1.js');console.time('计算时间');worker.postMessage(str);worker.onmessage=e=>{console.timeEnd('计算时间');}})这里我们改用FileReader的readAsText,读出的是一个字符串,长度为95,855,954,长度约9500万,耗时约118ms。同样,我把上面的空文本文件改成什么都没有,大约用了17ms。让我们尝试使用readAsDataURL来查看读取的数据多长时间fetch('./case.psd').then(file=>{returnfile.blob();}).then(blob=>{returnnewPromise(resolve=>{letfileReader=newFileReader();fileReader.onload=e=>{resolve(e.target.result);}fileReader.readAsDataURL(blob);})}).then(str=>{console.log(str.length);letworker=newWorker('1.js');console.time('计算时间');worker.postMessage(str);worker.onmessage=e=>{console.timeEnd('计算时间时间');}})读出一个长度为128,184,345的字符串,长度约为128亿,耗时约85ms(虽然字符串长度较长,但耗时较短)。工作线程单向传输数据耗时。结论传输数据的开销几乎为零(因为它与传递空字符串所花费的时间大致相同)。对于值的传递,不同的数据类型有不同的耗时,ArrayBuffer
