【问题标题】:Does the UI thread have priority over web workers?UI 线程是否优先于网络工作者?
【发布时间】:2018-04-15 16:56:40
【问题描述】:

如果我在 Web Worker 中进行数秒长的计算,我可以期望 UI 不会因此而卡顿吗?包括手机?如果没有,我该怎么办?工作负载很容易分成更小的块,但大约一半的站点在计算完成之前无法工作。

【问题讨论】:

  • 这个 2012 年的轶事证据似乎表明,在当时,UI 线程在繁重的 web worker 负载下陷入困境stackoverflow.com/questions/9758999/…
  • massivelong 计算 有点主观。一般来说,web worker 上的负载不应该影响 UI 线程。您能否详细解释一下您要向工作人员卸载的内容?

标签: javascript web-worker


【解决方案1】:

...我可以期望 UI 不会因此而卡顿吗?

很大程度上,是的,您可以在浏览器和设备的能力范围内。毕竟,这是网络工作者的存在理由:将长时间运行的进程移出 UI 线程,以便 UI 可以保持响应。没有任何保证,但是...根据经验:我已经完成了测试,在主 UI 更新时,worker 忙循环 30 多秒,它在桌面、Android 和 iOS 上运行良好。

这样的测试并不难:

Live on plnkr

Live sn-p(由于我创建工作器的方式,可能无法在所有设备上运行):

const chars = "|/-\\".split("");
let charindex = -1;
const spinner = document.getElementById("spinner");
setInterval(() => {
    charindex = (charindex + 1) % chars.length;
    spinner.innerHTML = chars[charindex];
}, 50);
function log(msg) {
    const p = document.createElement("pre");
    p.appendChild(document.createTextNode(msg));
    document.body.appendChild(p);
}
function main() {
    const url = URL.createObjectURL(
      new Blob([
        document.getElementById("worker").textContent
      ], {type: "text/javascript"})
    );
    const w = new Worker(url);
    w.onmessage = function(event) {
        if (event.data === "ready") {
            w.postMessage("start");
        } else {
            log(event.data);
        }
    };
}
main();
<div id="spinner"></div>
<script id="worker" type="worker">
this.addEventListener("message", e => {
    if (e.data === "start") {
        let last = Date.now();
        const stop = last + 20000;
        let now;
        while ((now = Date.now()) < stop) {
            if (now - last > 1000) {
                postMessage("tick");
                last = now;
            }
        }
    }
});
postMessage("ready");
</script>

worker.js:

this.addEventListener("message", e => {
    if (e.data === "start") {
        let last = Date.now();
        const stop = last + 30000;
        let now;
        while ((now = Date.now()) < stop) {
            if (now - last > 1000) {
                postMessage("tick");
                last = now;
            }
        }
    }
});
postMessage("ready");

host.html:

<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>Worker Host</title>
<style>
body {
    font-family: sans-serif;
}
</style>
</head>
<body>
<div id="spinner"></div>
<script>
const chars = "|/-\\".split("");
let charindex = -1;
const spinner = document.getElementById("spinner");
setInterval(() => {
    charindex = (charindex + 1) % chars.length;
    spinner.innerHTML = chars[charindex];
}, 50);
function log(msg) {
    const p = document.createElement("pre");
    p.appendChild(document.createTextNode(msg));
    document.body.appendChild(p);
}
function main() {
    const w = new Worker("worker.js");
    w.onmessage = function(event) {
        if (event.data === "ready") {
            w.postMessage("start");
        } else {
            log(event.data);
        }
    };
}
main();
</script>
</body>
</html>

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2016-02-21
  • 2012-08-21
  • 1970-01-01
  • 2018-11-29
  • 2013-03-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多