由于浏览器 GUI 渲染线程与 JS 引擎线程是互斥的关系,当页面中有很多长任务时,会造成页面 UI 阻塞,出现界面卡顿、掉帧等情况
查看页面的长任务:
打开控制台,选择 Performance 工具,点击 Start 按钮,展开 Main 选项,会发现有很多红色的三角,这些就属于长任务(长任务:执行时间超过 50ms 的任务)
测试实验:
如果直接把下面这段代码直接丢到主线程中,计算过程中页面一直处于卡死状态,无法操作。
代码语言:javascript复制let sum = 0;
for (let i = 0; i < 200000; i ) {
for (let i = 0; i < 10000; i ) {
sum = Math.random()
}
}
使用 Web Worker 执行上述代码时,计算过程中页面正常可操作、无卡顿。
代码语言:javascript复制// worker.js
onmessage = function (e) {
// onmessage获取传入的初始值
let sum = e.data;
for (let i = 0; i < 200000; i ) {
for (let i = 0; i < 10000; i ) {
sum = Math.random()
}
}
// 将计算的结果传递出去
postMessage(sum);
}
Web Worker 的通信时长
并不是执行时间超过 50ms 的任务,就可以使用 Web Worker,还要先考虑通信时长的问题
假如一个运算执行时长为 100ms,但是通信时长为 300ms, 用了 Web Worker 可能会更慢
比如新建一个 web worker, 浏览器会加载对应的 worker.js 资源,下图中的 Time 是这个资源的通信时长(也叫加载时长)
「当任务的运算时长 - 通信时长 > 50ms,推荐使用 Web Worker」