Под знаменем HTML5

JavaScript API: труженик Web Workers

В этой статье познакомимся с механизмом Web Workers, позволяющим организовать выполнение нескольких скриптов одновременно в фоновом режиме. Этот механизм является существенным изменением работы браузера.


Здравствуй, рабочий класс

Если новая функциональность для работы с файлами в браузерах, рассмотренная нами в предыдущем номере "КВ", не является такой уж новационной, то механизм параллельных вычислений - это то, чего в браузерах ещё не было. Если не считать, конечно, возможности организации параллельных вычислений с помощью дополнительного модуля GoogleGears, который существовал для некоторых браузеров и дальнейшее развитие которого, кстати, приостановлено.

А всё дело в том, что основная задача JavaScript первоначально была совсем незатейливой - обеспечить манипуляции с деревом DOM, или, проще говоря, обеспечить интерактивность веб-страницы на экране монитора. Различные несложные визуальные спецэффекты - вот и вся специфика применения JavaScript. Писать какие-то сложные вычисления на этом скриптовом языке никому и в голову не приходило.

Всё это время движок JavaScript в браузерах работал в однопоточном режиме. Так как основной задачей этого движка была только работа с DOM-деревом, дабы побаловать пользователя интерактивностью, такой однопоточности хватало за глаза. Добавление в JS-скрипт каких-то сложных числодробительных операций было делом неуместным, так как сразу же замедляло и тормозило отображение страницы в браузере. Сложные же вычисления производятся обычно на стороне сервера, а результаты возвращаются в браузер через интерфейс AJAX.

Однако незаметно наступила эпоха сложных веб-приложений. И эта эпоха потребовала выполнять часть вычислений не только на стороне сервера, но и на стороне браузера. А в дальнейшем предполагается экспансия офлайновых веб-приложений, в которых все производительные вычисления будут делаться только в браузере. И классическая однопоточность JavaScript совсем не соответствует требованиям времени.

Поэтому появление в браузерах механизма Web Workers можно считать ответом на вызовы текущей эпохи. С появлением механизма "веб-рабочий" можно числодробительные операции не отправлять на сервер, а выполнить их прямо в браузере. Причём это не должно сказываться на скорости основного скрипта, так как режим "рабочий" выполняется асинхронно.

Если же говорить образно, то раньше JavaScript в браузере можно было сравнить с офисным служащим, который просто перебирает в офисе бумажки и не выполняет какой-либо трудоёмкой работы. А теперь к этому "интеллигенту" в лице Web Workers добавлен настоящий работяга, который способен выполнять сложные, тяжёлые и продолжительные вычисления.


Техническая реализация

Познакомимся с веб-рабочим поближе. Механизм Web Workers позволяет запускать код JavaScript отдельным потоком. Чтобы задействовать этот механизм в браузере, сначала следует все числодробительные функции оформить отдельным файлом. После чего нужно просто создать экземпляр "рабочего", передав ему ссылку на этот отдельный файл.

new Worker('script.js');

В результате будет запущен отдельный поток, в котором будет выполнен загруженный код, а основной скрипт может спокойно продолжить свою работу с DOM-деревом, не ожидая завершения трудоёмких вычислений.

Конечно же, механизм Web Workers предполагает определённые нюансы и ограничения при взаимодействии с веб-страницей и вызвавшим его скриптом.

Во-первых, "веб-рабочий" не имеет никакого доступа к веб-странице и к её DOM-дереву. И это хорошо, потому как возможность доступа нескольких процессов одновременно к странице может обернуться настоящим кошмаром.

Во-вторых, взаимодействие основного скрипта и "веб-рабочего" происходит только через строковые сообщения посредством методов onmessage, postMessage. Сообщение может быть отослано "рабочему", так и "рабочий" может ответить родительской странице собственным сообщением.

Как и положено, проиллюстрируем сказанное примером очень высококачественного open source кода. Например, на веб-странице нам нужно просчитать локальный ядерный взрыв. Если считать этот взрыв в главном потоке, то эта веб-страница надолго зависнет, пока не выполнятся все расчёты. Поэтому лучше оформить ядерные вычисления в отдельный скрипт и запустить его через механизм Web Workers.

Листинг кода для веб-страницы

// Создаём рабочего
var worker = new Worker("nuclear.js");
// Ожидание сообщений от worker
worker.onmessage = function(e){
// Сообщение от worker:
e.data;
alert(e.data);
};
// Запускаем worker
worker.postMessage("go");

Листинг вспомогательного скрипта nuclear.js

onmessage = function(e){
if ( e.data == "go" ) {
// Выполняем сложные вычисления
var nuclear_explosion = "BABAH!!!";
// Отправляем полученный результат
postMessage(nuclear_explosion);
}
}; 

Скрипт проверен в браузерах Firefox 3.7 и Opera 10.60, которые с недавних пор поддерживают этот режим выполнения JavaScript.


Резюме

Таким образом, как видим, в браузерах появилась функциональность, которая раньше обеспечивалась только через сервер. А теперь на стороне клиента есть и собственная БД в лице Web SQL, и собственная возможность произвести производительные вычисления Web Workers. В результате прикладная программа может работать очень гибко, когда в одном случае можно использовать внутренние вычислительные ресурсы, в другом случае могут использоваться облачные мощности.

Реализация механизма Web Workers, скорее всего, потребует возможностей операционных систем. Читатели на форуме после статьи о тестировании браузера Opera просили делать тесты браузеров на нескольких операционных системах. И здесь нужно заметить, что обычные JS-скрипты не используют системные возможности, и чистый JavaScript показывает в тестах практически одинаковые результаты - что на Windows, что на Linux. А вот режим Web Workers может продемонстрировать различия в скорости для разных ОС.

Михаил АСТАПЧИК

Версия для печатиВерсия для печати

Номер: 

26 за 2010 год

Рубрика: 

Internet
Заметили ошибку? Выделите ее мышкой и нажмите Ctrl+Enter!