web worker 的传值方式以及耗时对比
背景
前一阵子开发的项目 pptx 导入
, 由于自己的代码问题,引起了个性能问题,一个 40p 的 pptx 文件,转换成 json 数据,大概要耗时 60s+ ,虽然后面发现是某个使用频率非常高的函数内部,用了 new Function 构造函数
造成的(所以这里顺便提醒一下,如果你很在乎几毫秒的差距的话,建议谨慎使用哈),但是在优化的过程中,一度怀疑是性能达到了瓶颈,所以尝试了使用 web worker 去优化,由于是文件,一般内容都比较大,发现 web worker 在传值这块占用了大部分的时间,所以想开这篇来详细聊聊.
两种传值方式
关于 web worker 的基本用于以及传值方式,网上以及有一大堆介绍了,这里就不赘述了,这里我们重点来看一下同一个文件用两种方式来传值,会有多大的差别,这边随意从电脑里面找了一个 96MB 的 PSD 文件来测试.
主线程
fetch('./case.psd').then(file => {return file.blob();}).then(blob => {return new Promise(resolve => {let fileReader = new FileReader();fileReader.onload = e => {resolve(e.target.result);}fileReader.readAsArrayBuffer(blob);})}).then(buf => {let worker = new Worker('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 的字符串,长度大概 0.96 亿, 耗时大概 70ms 左右(同一个台电脑取 10 次平均值,下同)
我们稍微改一下上面主线程的代码,改用 转移数据
的方式
- worker.postMessage(buf);+ worker.postMessage(buf, [buf]);
同样的数据, 耗时大概 17ms 左右,这 17ms 好像是个固定值,我尝试换了个 800MB+ 的文件和一个里面啥都没有的空文本文件,大概都是这个时间.
不同的数据类型,用值传递的耗时也是不一样的
fetch('./case.psd').then(file => {return file.blob();}).then(blob => {return new Promise(resolve => {let fileReader = new FileReader();fileReader.onload = e => {resolve(e.target.result);}fileReader.readAsText(blob);})}).then(str => {console.log(str.length);let worker = new Worker('1.js');console.time('计算时间');worker.postMessage(str);worker.onmessage = e => {console.timeEnd('计算时间');}})
这里我们改用 FileReader 的 readAsText,读出来是一个长度为 95,855,954 的字符串,长度大概 0.95 亿, 耗时大概 118ms 左右,同样我换了上面那个里面啥都没有的空文本文件,耗时也是 17ms 左右.
那我们试试用 readAsDataURL 看看读出来的数据要多久
fetch('./case.psd').then(file => {return file.blob();}).then(blob => {return new Promise(resolve => {let fileReader = new FileReader();fileReader.onload = e => {resolve(e.target.result);}fileReader.readAsDataURL(blob);})}).then(str => {console.log(str.length);let worker = new Worker('1.js');console.time('计算时间');worker.postMessage(str);worker.onmessage = e => {console.timeEnd('计算时间');}})
读出来是一个长度为 128,184,345 的字符串,长度大概 1,28 亿, 耗时大概 85ms 左右(虽然字符串长度更长,但是耗时却更短)
以上耗时,均为主线成向 worker 线程单向传递数据的耗时.
结论
- 转移数据几乎是零开销(因为和传递空字符串的耗时是差不多的).
- 值传递的话,不同的数据类型,耗时也有差别,ArrayBuffer < base64 < 普通字符串.
- postMessage 传递消息,除了发送数据的耗时外,还有其他开销(就是上面的 17ms). 当然每台电脑性能不一样,耗时也是不一样的,不过按比例来看,这个占比还挺大的.
关于转移的缺点, 网上也是有很多的, 这里也就不啰嗦了, 总结一句就是数据无法同时在2个线程上使用.
另外个人觉得如果是普通的数据,为了转移而去转换成 Transferable objects
的话, 大部分情况下是划不来的, 因为你需要在花在编码解码上的时间,会比直接传递花的时间多.
另外, 如果你是要用子线程处理图片的话, ImageBitmap
格式 配合最近新鲜出炉的 OffscreenCanvas
也许是不错的选择.前提是你不需要考虑兼容性问题.
最后是广告时间
我们40人的前端团队常年招兵买马中,在厦门的和想来厦门的童鞋们,不要吝惜你的简历,使劲砸过来 邮箱:nuoya@gaoding.com
, 期待你一起来稿事
原文地址 https://github.com/noahlam/ar...
转载于:https://www.cnblogs.com/qixidi/p/10390960.html
web worker 的传值方式以及耗时对比相关推荐
- 【有趣的实验】JAVA 遍历数组的几种方式的耗时对比
一.前言 出于对遍历方式的耗时想法,是普通for循环.fori.foreach.迭代器 iterator.还是steam流的形式哪种耗时更少呢? 首先添加一个List 集合,这边采用ArraryLis ...
- web worker原理 SSE原理
第一部分 什么是 web worker? 我们一直强调JavaScript是单线程的,但是web worker的出现使得JavaScript可以在多线程上跑,只是web worker本身适合用于一些复 ...
- Service Worker,Web Worker,WebSocket的对比
Service Worker 处理网络请求的后台服务.适用于离线和后台同步数据或推送信息.不能直接和dom交互.通过postMessage方法交互. Web Worker 模拟多线程,允许复杂计算功能 ...
- 一文搞懂 Web Worker(原理到实践)
作者:poetry 原文地址:https://mp.weixin.qq.com/s/XF7qOhbBtYlwADCiyxbT-w Web Worker 作为浏览器多线程技术,在页面内容不断丰富,功能日 ...
- Web Worker 初探
(给前端大全加星标,提升前端技能) 作者:SHERlocked93 juejin.im/post/5b4af72ae51d45198d4b1388 以前我们总说,JS是单线程没有多线程,当JS在页面中 ...
- JavaScript多线程之HTML5 Web Worker
在博主的前些文章Promise的前世今生和妙用技巧和JavaScript单线程和浏览器事件循环简述中都曾提到了HTML5 Web Worker这一个概念.在JavaScript单线程和浏览器事件循环简 ...
- PWA(Progressive Web App)入门系列:(五)Web Worker
前言 在说Service Worker前有必要说一下Web Worker,因为Service Worker本身就属于Web Worker的延伸,大部分功能也是基于Web Worker进行的扩展. 背景 ...
- 一文了解Web Worker
一.概述 众所周知,JavaScript最初设计是运行在浏览器中的,为了防止多个线程同时操作DOM带来的渲染冲突问题,所以JavaScript执行器被设计成单线程.但是随着前端技术的发展,JavaSc ...
- HTML加js实现计算文件哈希值,HTML5 File API 配合 Web Worker 计算大文件 SHA3 Hash 值
这学期的安全学课程有个作业,内容是写一个软件实现 SHA3 Hash 值的快速计算.想一想老师这么安排,大致上也有一种推广新的密码学算法的意图.既然希望应用起来,天然跨平台的 Web 显然是一项非常具 ...
- Web Worker,Service Worker,Web Worker
Web Worker.Worker Service和Service Worker Web Worker.Worker Service和Service Worker Service Worker.Wor ...
最新文章
- 类执行方法的过程与运行时
- 利用sendmail搭建邮件服务器
- python语言做法_python学习笔记(十六)
- Jquery 日历控件
- 触发器如何通知websocket_「Web应用架构」如何扩展WebSockets
- 三维点云学习(5)1-introduction on to Deep learning
- antd的select的滚动条怎么才会出现_纵向滚动条对横向滚动条的影响
- 16QAM的理论误码率仿真
- 电商管理后台 API 接口文档
- 当马队遭遇狼群,阿里华为长篇竞合剧基情开幕
- 为出海掘金创造更多可能 助力开发者触达全球用户
- win7怎么查看计算机用户名,Win7怎么查看自己电脑ip地址?
- pytorch之torch.zeros_like
- 计算机环境安全容器服务未启动怎么解决,音频服务未运行|音频服务未启动 - 音频服务未运行的解决办法 - 安全专题...
- jQuery中所用到的第三方插件
- ASUS华硕/RT-AC1200GU vs TP-LINK双千兆WDR6500
- 第十七章 使用系统监视器 - 使用 ^%SYSMONMGR 实用程序
- xml建模包括以下_()是专业建模语言。A.XMLB.UMLC.VC++D.JAVA - 信管网
- 桂电信科17级c语言期末试卷,桂电期末考试Linux习题总结
- 超越股神的贝佐斯:“我可是在做一件大事”
热门文章
- PollingBlockTracker - encountered an error while attempting to update latest block:
- 区块链 自私挖矿(selfish mining)是什么
- -1交替c语言代码,排序(1)---------选择排序(C语言实现)(示例代码)
- mysql 导入 druid,Druid数据库连接池的使用(非常实用!!!)
- A non well formed numeric value encountered
- 十四、Oracle学习笔记:集合操作
- Logstash 日志搜集处理框架 安装配置
- 阶段3 3.SpringMVC·_04.SpringMVC返回值类型及响应数据类型_2 响应之返回值是String类型...
- 阶段2 JavaWeb+黑马旅游网_15-Maven基础_第5节 使用骨架创建maven的java工程_11使用骨架创建maven的java工程...
- 阶段1 语言基础+高级_1-3-Java语言高级_08-JDK8新特性_第1节 常用函数接口_5_函数式接口作为方法的参数案例...