Если я выполняю многосекундные вычисления в веб-воркере, могу ли я ожидать, что пользовательский интерфейс не будет заикаться из-за этого? В том числе мобильный? Если нет, что я могу с этим поделать? Рабочую нагрузку легко разделить на более мелкие части, но примерно половина сайта не работает, пока не будут выполнены эти вычисления.
Имеет ли поток пользовательского интерфейса приоритет над веб-работниками?
comment
Это неподтвержденное свидетельство из 2012 года, кажется, говорит о том, что тогда поток пользовательского интерфейса забивался на большую нагрузку веб-работника веб-сайты-web-workers-or-cgi" title="как обрабатывать массивные вычисления на веб-сайтах веб-воркеров или cgi"> stackoverflow.com/questions/9758999/
- person Filip Haglund   schedule 15.04.2018
comment
массивные и долгие вычисления немного субъективны. Как правило, нагрузка на веб-воркер не должна влиять на поток пользовательского интерфейса. Можете ли вы объяснить немного больше о том, что вы пытаетесь разгрузить в работника?
- person Nisarg   schedule 15.04.2018
Ответы (1)
... могу ли я ожидать, что пользовательский интерфейс не будет заикаться из-за этого?
В основном да, можно, в пределах возможностей браузера и устройства. В конце концов, это смысл существования веб-воркеров: вывести длительные процессы из потока пользовательского интерфейса, чтобы пользовательский интерфейс мог оставаться отзывчивым. Гарантий нет, но... Эмпирически: я проводил тесты, в которых рабочий цикл зацикливался на 30+ секунд, пока обновлялся основной пользовательский интерфейс, и он отлично работал на настольных компьютерах, Android и iOS.
Такие испытания не сложны:
Живой фрагмент (может работать не на всех устройствах из-за того, как я создаю работника):
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>
person
T.J. Crowder
schedule
15.04.2018
Да, я нашел pmav.eu/stuff/javascript-webworkers и запустил его с 16+ потоки без слишком большой задержки пользовательского интерфейса на рабочем столе или на мобильном устройстве
- person Filip Haglund; 15.04.2018