Comments 6
Возможно стоит добавить что до Web Workers тяжёлые скрипты «деблокировались» другими средствами, например используя setTimeout(fn, 0). Несмотря на очевидную «костыльность» этого — перетаскивание кучи зависимостей в Worker на мой взгляд не сильно лучше.
Нет. setTimout — просто отсрочит выполнение скрипта (до тех пор пока не выполняться все синхронные вычисления), но потом fn всё равно будет выполняться в основном потоке, и «фризнет» страницу. В случае же с webworker, fn будет выполняться в отдельном потоке не влияющем на основной (собственно потому там нет доступа к dom и прочему окружению).
Там изначально расчёт идёт чтобы не «фризить» сразу на 3 секунды страницу одним куском, а синхронно проделав часть работы (допустим за 1/20 с) дать возможность другим сообщениям отработать, повесив остаток работы на «потом» и так 60 раз :).
Вместо одного большого фриза будет много маленьких фризят — но они конечным пользователем воспринимаются терпимее.
Вместо одного большого фриза будет много маленьких фризят — но они конечным пользователем воспринимаются терпимее.
Worker выполняется в отдельном потоке, который создаёт браузер. То есть он выполняется паралельно, в другом «месте» и никак не тормозит основную страницу. Плюс этот поток сильно урезан в фичах, например там нет DOM, что делает его ещё более лёгким.
Удобнее все же
workerScript
не строкой хранить:let workerFunctionString = function () {
// тут можно использовать только глобальные функции
let privateData = {
// ...
};
function privateMethod() {
// ...
}
onmessage = function (msg) {
// пришел запрос от основного окна
// ...
postMessage({
// ответ основному окну
// ...
});
};
// готов работать
postMessage('ready');
}.toString();
let blobURL = URL.createObjectURL(new Blob(['(', workerFunctionString, ')()'], {type: 'application/javascript'}));
let myWorker = new Worker(blobURL);
URL.revokeObjectURL(blobURL);
let workerReadyCallback = function (message) {
if (message.data === 'ready') {
// воркер запустился
removeEvent(myWorker, 'message', workerReadyCallback);
myWorker.postMessage({
// запускаем, что нужно
// ...
});
}
};
addEvent(myWorker, 'message', workerReadyCallback);
Sign up to leave a comment.
Прослушиватели событий и веб-воркеры