本周 JavaScript 436期周报连接。这里面主要我想谈谈 WebWorker 相关的内容。javascript
众所周知,JavaScript 使用运行在单线程上的。可是 JavaScript 能够处理异步代码,其中 Ajax 就是个很好的例子。异步带来的用户体验没必要多说,可是这里有个问题:若是异步以后的成功回调是一次密集 CPU 操做。那么原本由于异步而产生的非阻塞用户体验,就又会由于没法从事件循环出解脱而又产生阻塞。对用户而言便又产生了不响应的 UI。这种状况,咱们能够认为 JavaScript 只是解决了单线程的部分限制。能够假设,若是咱们把这一次密集 CPU 操做也在异步中执行,那么用户体验仍然一如既往地流畅。html
Web Worker 就应用而生了。前端
Web Worker 是真正的多线程。java
Web Worker并不会阻塞事件循环。参考这个 demo 能够看到在 5 万条数据排序的时候,使用 WebWorker 带来的体验差异。Web Worker 并非 JavaScript 的一部分,它是经过 JavaScript 能够访问的浏览器特性。然而,Web Worker 并无在 Node.js 中实现,有点像子进程的概念,可是却有不一样。git
Web Worker是有三种类型,在 MDN 中有详细定义:github
其中,专用 Workers 是经过主进程实例化,也只能经过主进程通讯;共享 Workers 能够访问全部同源的进程(在不一样的浏览器标签,窗口或者其余的共享 Workers);服务 Workers 是针对源和路径的事件驱动 worker,用在网络不可用的状况下,能够控制网站和相关站点,插入和修改导航和资源请求,缓存资源等。web
Web Workers 在浏览器中运行一个独立的线程。正因如此,执行的代码须要被包含在一个独立的文件中,这一点比较重要。使用方式也很简单:浏览器
var worker = new Worker('taks.js');
复制代码
浏览器会建立一个异步下载的文件线程。当下载完成后,会被执行。经过调用 postMessage
方法来使用建立好的 worker。它可让一个 Web Worker 和页面之间通讯。缓存
比较新的浏览器支持 JSON 做为第一个参数,而旧的浏览器只支持字符串。安全
<button onclick="startComputation()">Start computation</button>
<script> function startComputation() { worker.postMessage({'cmd': 'average', 'data': [1, 2, 3, 4]}); } var worker = new Worker('doWork.js'); worker.addEventListener('message', function(e) { console.log(e.data); }, false); </script>
复制代码
在 new 一个 Worker 以后,给它的实例注册一个叫 message
的监听事件。同时在咱们的 doWork.js
里,也要注册相同事件用来处理数据。
self.addEventListener('message', function(e) {
var data = e.data;
switch (data.cmd) {
case 'average':
var result = calculateAverage(data); // Some function that calculates the average from the numeric array.
self.postMessage(result);
break;
default:
self.postMessage('Unknown command');
}
}, false);
复制代码
当消息到达的时候,worker 就开始执行计算,具体来讲运行 calulateAverage
方法。结束以后,把结果传递给主页面。在 worker 的上下文环境中,self
和 this
都是 worker 的全局,与 window 无关。有两种方式能够结束 worker: worker.terminate()
和 self.close()
。
navigator
对象location
对象(只读)XMLHttpRequest
setTimeout()/clearTimeout()
和 setInterval()/clearInterval()
importScripts()
导入外部脚本window
对象document
对象parent
对象光线追踪
为了模拟光线路径,这种场景是须要大量计算的,可是不能再每次大量计算的时候就让光线变得卡顿或者不天然,这时候workers 就能够发挥做用了。
加密
也是纯粹的计算工做,交给 web workers 正当其用。并且有些加密解密的操做是至关消耗时间的。
预加载数据 当网络不是很稳定的时候,能够先把数据取出来存在本地浏览器缓存中,这样在须要的时候就会减小延迟感
拼写检查
若是对应的检查数据是一本字典的话。这种场景下,使用 web worker 就十分必要了。
总结一下使用 Web Workers 的场景的共同点:
Web Worker 是个浏览器实现的特性,尽管如此,咱们仍是可以在某些地方发挥它的优点去加强用户体验,遵循“渐进加强,平稳退化”得原则。没有理由去拒绝使用它。但其实,Web Worker 的使用场景也十分具备特色,它应该不是做为解决卡顿问题的首选,由于在前端,除了动画之外每每没有特别大的计算量。大多数的不流畅用户体验,多半是重绘和重排没有优化好而引发的,千万不可缘木求鱼,为了 Web Worker 什么都往上鼓捣。