Если вы попытаетесь выполнить тяжелую, интенсивную задачу с помощью JavaScript, который занимает много времени и требует изрядных вычислений, браузер заморозит веб-страницу и не даст пользователю ничего сделать, пока работа не будет завершена. Это происходит потому, что код JavaScript всегда прерывает рендеринг документа.
HTML5 представляет новую технологию, называемую веб-работником (Web Worker), которая специально разработана для выполнения фоновой работы независимо от других сценариев пользовательского интерфейса, не влияя на производительность страницы. В отличие от обычных операций JavaScript, web worker не прерывает работу пользователя, и веб-страница остается отзывчивой, поскольку задачи выполняются в фоновом режиме.
Функция Web Worker HTML5 поддерживается во всех современных веб-браузерах, таких как Firefox, Chrome, Opera, Safari и Internet Explorer 10 и выше.
Создание Web Worker файла
Web worker используется для выполнения трудоемких задач. Здесь мы собираемся создать задачу JavaScript, которая будет насчитывать до 100 000 операций.
Давайте создадим внешний JavaScript-файл с именем worker.js
и наберем следующий код.
var i = 0;
function countNumbers() {
if(i < 100000) {
i = i + 1;
postMessage(i);
}
// Wait for sometime before running this script again
setTimeout("countNumbers()", 500);
}
countNumbers();
Web worker не имеет доступа к DOM. Это означает, что вы не можете получить доступ к любым элементам DOM в коде JavaScript, который вы собираетесь запускать с помощью web worker.
Метод postMessage()
рабочего объекта используется для отправки сообщения (например, чисел в приведенном выше примере) обратно на веб-страницу из файла web worker.
Работа с Web Worker в фоновом режиме
Теперь, когда мы создали наш web worker файл, нам нужно инициировать его из HTML-документа, который запустит код в файле с именем worker.js
в фоновом режиме и будет постепенно отображать результат на веб-странице. Давайте посмотрим, как это работает:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Using Web Worker</title>
<script>
if(window.Worker) {
// Create a new web worker
var worker = new Worker("worker.js");
// Fire onMessage event handler
worker.onmessage = function(event) {
document.getElementById("result").innerHTML = event.data;
};
} else {
alert("Sorry, your browser do not support web worker.");
}
</script>
</head>
<body>
<div id="result">
<!--Received messages will be inserted here-->
</div>
</body>
</html>
JavaScript-код в приведенном выше примере имеет следующие значения:
- Оператор var worker = new Worker(«worker.js»); создает новый web worker объект, который используется для связи с ним.
- Когда web worker отправляет сообщение, он запускает обработчик события onmessage (строка 14), который позволяет коду получать от web worker сообщения.
- Элемент event.data содержит сообщение, отправленное веб-web worker.
Код должен всегда хранится в отдельном файле JavaScript. Это делается для того, чтобы веб-разработчик не писал код web worker, который пытается использовать глобальные переменные или напрямую получить доступ к элементам на веб-странице.
Завершение работы Web Worker
Вы всегда можете завершить работающий web worker в середине выполнения скрипта.
В следующем примере показано, как запускать и останавливать работника с веб-страницы с помощью HTML-кнопок. Он использует тот же JavaScript-файл worker.js
, который мы использовали в предыдущем примере для подсчета чисел от нуля до 100 000. Давайте посмотрим:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Start/Stop Web Worker</title>
<script>
// Set up global variable
var worker;
function startWorker() {
// Initialize web worker
worker = new Worker("worker.js");
// Run update function, when we get a message from worker
worker.onmessage = update;
// Tell worker to get started
worker.postMessage("start");
}
function update(event) {
// Update the page with current message from worker
document.getElementById("result").innerHTML = event.data;
}
function stopWorker() {
// Stop the worker
worker.terminate();
}
</script>
</head>
<body>
<h1>Web Worker Demo</h1>
<button onclick="startWorker();" type="button">Start web worker</button>
<button type="button" onclick="stopWorker();">Stop web worker</button>
<div id="result">
<!--Received messages will be inserted here-->
</div>
</body>
</html>
Используйте web worker для выполнения только тяжелых JavaScript-задач, которые не относятся к скриптам пользовательского интерфейса (то есть скрипты, которые реагируют на клики или другие взаимодействия с пользователем). Не рекомендуется использовать web worker для коротких задач.