前面章节我们梳理了woker的相关理论。下面让我们结合具体代码看看使用worker带来的变化
如上,我们做一个输入框,输入大数字,计算从1到给定数值的总和,点击按钮开始计算,模拟一下复杂计算。
1、代码
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Worker演练</title>
</head>
<body>
<!-- 输入 10000000000-->
<div>计算从 1 到给定数值的总和</div>
<div>
<input type="text" placeholder="请输入数字" id="num1" />
<button id="singleRef">主线程计算</button>
<span>计算结果为:<span id="result1">-</span></span>
</div>
<div>
<input type="text" placeholder="请输入数字" id="num2" />
<button id="multipleRef">worker计算</button>
<span>计算结果为:<span id="result2">-</span></span>
</div>
<div>在计算期间你可以填XX表单</div>
<input type="text" placeholder="请输入姓名" />
<input type="text" placeholder="请输入年龄" />
<script type="module" src="./multiple.js"></script>
<script type="module" src="./single.js"></script>
</body>
</html>
js
//主线程运算
//single.js
singleRef.onclick = () => {
const num = parseInt(document.getElementById('num1').value)
let result = 0
console.log('%c 开始主线程测试 ', 'color:#fff; background:#00897b ')
console.time('主线程执行时间')
for (let i = 0; i <= num; i++) {
result += i
}
// 由于是同步计算,在没计算完成之前下面的代码都无法执行
console.timeEnd('主线程执行时间')
document.getElementById('result1').innerHTML = result
}
js
//multiple.js
//worker线程运算
multipleRef.onclick = () => {
console.log('%c 开始Worker测试 ', 'color:#fff; background:#00897b ')
const worker = new Worker('./worker.js')
const num = parseInt(document.getElementById('num2').value);
console.time('Worker执行时间')
worker.postMessage(num)
worker.onmessage = function (e) {
document.getElementById('result2').innerHTML = e.data
console.timeEnd('Worker执行时间')
}
}
js
//worker.js
function calc(num) {
let result = 0
// 计算求和(模拟复杂计算)
for (let i = 0; i <= num; i++) {
result += i
}
self.postMessage(result)
}
self.onmessage = function (e) {
calc(e.data)
}
2、交互对比与性能分析
我们分析在输入框输入较大数字,比如,10000000000,打开控制台,让我们从交互体验和性能两方面看一下对比。
2.1、就页面交互来看
- 主线程运算:
点击按钮,主线程处理一直在处理同步计算逻辑,在完成计算之前,会发现页面处于卡顿的状态,下方的两个输入框也无法点击交互,大约花了22s左右,结果渲染出来。但是这个卡顿时间给用户的体验就很差了。
- worker运算:
点击按钮, Worker 运行独立于主线程的后台线程中,分担执行了大量占用CPU密集型的操作,解放了主线程,主线程就能及时响应用户操作而不会造成卡顿的现象。点完按钮后可以立即操作下面xx表单。大约20s左右,计算结果渲染出来。
tips:以上时间说明worker并不会让计算时间明显变短。
2.2、就线程使用来看
打开控制台的性能数据分析面板,开始录制
- 主线程运算:
运行期间主线程打满
- worker运算:
运行期间主线程比较空闲,开启了DedicatedWorker
线程执行运算。
2.3、就CPU使用率来看
打开控制台性能监视器,可以观察代码运行时cpu的使用情况。
- 主线程运算:
CPU使用率是100%
- worker运算:
CPU使用率处于较低正常水平,计算过程跟没计算之前的水平一样。
3、简单运算使用worker
此时好奇宝宝就会问了,那么简单运算使用worker会是什么样呢,让我们试一下,输入10,看一下两者的运算时间。
可以看到使用worker 的执行时间明显大于不使用worker的执行时间多得多。这是为什么呢?
其实我们在上一章节也提到过,每次创建worker线程
以及possmessage通信
都是需要损耗
一些性能以及时间的。因此web worker是不可以滥用 的哦,日常开发中,建议在需要消耗比较多的cpu运算能力
的时候酌情使用。