Javascript 如何降低web worker HTML 5的CPU使用率

Javascript 如何降低web worker HTML 5的CPU使用率,javascript,html,animation,setinterval,web-worker,Javascript,Html,Animation,Setinterval,Web Worker,我正在使用web worker(WW)制作动画。我使用WW而不是setInterval来避免问题setInterval在选项卡处于活动状态时停止。但是WW似乎使用了太多的CPU,它总是占用至少37-38%的CPU。您能提供一些解决方案来减少这种使用吗?现场演示: 下面是我的代码。非常感谢你 Index.html: worker.js: let速度=0.05; onmessage=(ev)=>{ 常数{currentX,limit}=ev.data; 如果(当前X>=限制){ 速度=-0.05 }

我正在使用web worker(WW)制作动画。我使用WW而不是setInterval来避免问题setInterval在选项卡处于活动状态时停止。但是WW似乎使用了太多的CPU,它总是占用至少37-38%的CPU。您能提供一些解决方案来减少这种使用吗?现场演示:
下面是我的代码。非常感谢你

  • Index.html:
  • worker.js:
  • let速度=0.05;
    onmessage=(ev)=>{
    常数{currentX,limit}=ev.data;
    如果(当前X>=限制){
    速度=-0.05
    }
    
    如果(currentX它使用了大量CPU,因为正如评论中指出的,您要求工人在收到上一个响应后立即执行新作业

    在最好的情况下,main是空闲的,它能够直接处理worker的消息并发布一条新消息->甚至没有一次与它无关的worker事件循环迭代

    根据您的配置,这也意味着您要求main以每屏幕数千次的刷新率更新元素的位置,这真的不是一个好主意

    要解决这个问题,您应该在工作线程中使用某种计时器
    最近的浏览器也在这个上下文中添加了
    requestAnimationFrame
    方法,如果它不可用,您可以随时使用
    setTimeout

    但请注意,您使用Web Worker作为解决浏览器在后台选项卡中限制计时器的手段的整个想法很快就会失败。
    事实上,浏览器已经计划在不久的将来限制网络工作者,然后它将停止工作

    相反,您应该重构代码,以便它使用经过的时间来定义元素的位置(又称时间增量)。这样,不管页面是否被限制,元素都处于此时应该处于的位置

    const it=document.getElementById(“it”);
    const checkbox=document.querySelector(“输入”);
    const maxLeft=window.innerWidth-50;
    const duration=2000;//遍历屏幕的时间(毫秒)
    const start=performance.now();
    函数动画(现在){
    常量增量=((现在-开始)%duration)/duration;
    //决定我们是向左走还是向右走
    常量方向=数学符号((现在-开始%(持续时间*2))-持续时间);
    让位;
    如果(方向<0){
    位置=增量*最大左;
    }
    否则{
    位置=maxLeft-(增量*maxLeft);
    }
    it.style.left=位置+“px”;
    如果(复选框。选中){
    请求动画帧(anim);
    }
    }
    请求动画帧(anim);
    checkbox.oninput=anim;
    #它{
    宽度:50px;
    高度:50px;
    背景:红色;
    边界半径:50%;
    位置:固定;
    顶部:50px;
    }
    
    
    暂停/恢复
    好吧,您正在“尽可能快地”发布消息-因此cpu使用率将很高-建议您使用requestAnimationFrame来限制消息频率(不过您需要调整速度)我以前也使用RFA,它在setInterval上有一些问题,当tab处于活动状态时动画停止。这就是我使用web worker的原因。知道吗?worker中的setTimeout如何?
    最近的浏览器也在这个上下文中添加了requestAnimationFrame方法
    -哪些?我没有发现有文档记录的Anywhere Blink方法,它是nEded for Offscreen NVAS有一个注意事项,规格是最新的:(“
    专用WorkerGlobalScope包括AnimationFrameProvider;
    ”),也许MDN文章应该更新以使用WindowOrWorkerGlobalScope,但我想它可能会断开链接。。。
    <!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>
    
    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
        })
    };
    
    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)
    }