如何解决如何减少Web Worker HTML 5的CPU使用率
我正在使用网络工作者(WW)制作动画。我用WW,而不是使用setInterval的,以避免问题的时候标签是有源的setInterval停止。但是WW似乎使用了太多的CPU,因此它总是至少占用37-38%的CPU。您能建议任何解决方案如何减少这种使用吗?现场演示:https://repl.it/repls/SweetPowerlessKeychanger#worker.js
下面是我的代码。非常感谢。
- Index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>Web Worker 1</title>
<style>
#it {
width: 50px;
height: 50px;
background: red;
border-radius: 50%;
position: fixed;
top: 50px;
}
</style>
</head>
<body>
<div id="it"></div>
<script src="main.js"></script>
</body>
</html>
- Main.js(工人的母亲):
const it = document.getElementById("it");
it.style.left = "10px";
const maxLeft = window.innerWidth - 50;
const worker = new Worker("./worker.js");
worker.postMessage({
currentX: 10,limit: maxLeft
});
worker.onmessage = (ev) => {
const data = ev.data;
it.style.left = data + "px";
worker.postMessage({
currentX: parseFloat(it.style.left),limit: maxLeft
})
};
- worker.js:
let speed = 0.05;
onmessage = (ev) => {
const {currentX,limit} = ev.data;
if (currentX >= limit) {
speed = -0.05
}
if (currentX <= 0) {
speed = 0.05
}
postMessage(currentX + speed)
}
解决方法
它占用大量CPU,因为正如评论中指出的那样,您要在收到上一个响应后立即要求工作人员执行新工作。
在最佳情况下,main是空闲的,它能够直接处理工人的消息并发布新消息->甚至没有工人事件循环的任何迭代,它与工作无关。
这取决于您的配置,这还意味着您要main每次屏幕刷新率将元素的位置更新大约数千次,这确实不是一个好主意。
要解决此问题,您应该在工作线程中使用某种计时器 。
最近的浏览器也在这种情况下添加了requestAnimationFrame
方法,如果该方法不可用,您总是可以退回到使用setTimeout
的方式。
但是请注意,使用Web-Worker来解决浏览器在后台选项卡中的计时器调整问题的整个想法很容易很快失败。
实际上,浏览器已计划在不久的将来限制Web-Workers,然后它将停止工作。
相反,您应该重构代码,以便它使用经过的时间来定义元素的位置(又称时间增量)。这样,页面是否受到限制都无关紧要,您的元素处于此时应处于的位置。
const it = document.getElementById("it");
const checkbox = document.querySelector("input");
const maxLeft = window.innerWidth - 50;
const duration = 2000; // time to traverse the screen (ms)
const start = performance.now();
function anim( now ) {
const delta = ((now - start) % duration) / duration;
// determine if we should go to left or to right
const direction = Math.sign( ((now - start) % (duration * 2)) - duration );
let position;
if( direction < 0 ) {
position = delta * maxLeft;
}
else {
position = maxLeft - (delta * maxLeft);
}
it.style.left = position + "px";
if( checkbox.checked ) {
requestAnimationFrame( anim );
}
}
requestAnimationFrame( anim );
checkbox.oninput = anim;
#it {
width: 50px;
height: 50px;
background: red;
border-radius: 50%;
position: fixed;
top: 50px;
}
<div id="it"></div>
<label>pause/resume<input type="checkbox" checked></label>
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。