WebWorkers имеют глобальное покрытие в 92% по данным http://caniuse.com. Тем не менее, не всякое современное веб-приложение использует их.
В своем докладе я постараюсь передать двухлетний опыт использования WebWorkers в нашей команде для написания веб-приложений с функциональностью, которая требует выполнения тяжелых вычислений, таких как преобразование бинарых файлов из одного формата в другой и шифрование.
Расскажу про эксперименты по переносу в воркер расчета diff'ов в React-подобной системе рендеринга и покажу наивную реализацию модели акторов на основе воркеров.
Также постараюсь подготовить слушателей к новым проблемам, которые могут возникнуть при использовании веб-воркеров.
3. Обзор Web Workers
● Позволяют выполнять код параллельно с
основным потоком выполнения
● Не разделяют память
● Не разделяют код
● Обмениваются сообщениями
● Доступны для 92% пользователей*
* http://caniuse.com/#search=webworkers на ноябрь 2016
4. Обзор Web Workers
● Нельзя манипулировать DOM
● Не доступен localStorage
● Не доступен window.location
Полный список того, что доступно, можно прочитать здесь
https://goo.gl/ogcuiX
5. Обзор Web Workers
● Сообщения сериализуются
● Можно передать владение ArrayBuffer и
ImageBitmap
11. Асинхронность и параллелизм
onmessage = function(e) {
var messageId = e.data[0];
var messageBody = e.data[1];
var result = doSomething(messageBody);
postMessage([messageId, result]);
}
12. Асинхронность и параллелизм
function doInWorker(data) {
return new Promise(function(resolve, reject) {
var messageId = ++lastMessageId;
var onMessage = function(e) {
if (e.data[0] === messageId) {
resolve(e.data[1]);
worker.removeEventListener('message', onMessage);
}
};
worker.addEventListener('message', onMessage);
worker.postMessage([messageId, data]);
})
}
13. Применение: шифрование
● Храним приватные данные в localStorage
● Шифрование ресурсоемко
● Использовали
https://github.com/vibornoff/asmcrypto.js/
14. Применение: конвертация файлов
● Мобильное приложение (PhoneGap)
● Храним большие документы
● Работаем в оффлайне
● Конвертация занимает много времени
● Спасение в живительных воркерах
15. Применение: переносим в воркер вообще все
● Вся логика выполняется в воркере
● В основном потоке остается работа с DOM и
localStorage
● Страница никогда не подвисает
16. Применение: переносим в воркер вообще все
WebWorker
Transition
Render
State
Commands
DOM thread
Apply changes to
DOM
Listen events on
document.body
EventsServer push
17. Применение: переносим в воркер вообще все
Мои наработки по теме (Scala.js)
● https://github.com/tenderowls/moorka
● https://github.com/fomkin/korolev
● https://medium.com/@yelbota/-18195d44f574
18. Проблема: дублирование кода
● Своя “система модулей” importScript
● Ничего не знают про код, загруженный
через <script>
● Боль и страдание
19. Проблема: воркеры не бесплатны
● Воркер ― отдельный инстанс
виртуальной машины (в первом
приближении)
● Затраты на переключение контекста
● Затраты на запуск
Не создавайте тысячи воркеров.
Это вам не эрланг.
20. Проблема: сериализация
● Передавая сообщение, мы сначала
пишем его JSON, потом читаем (в
первом приближении)
● ArrayBuffer копируется, если мы не
указали, что он transferable.
Убедитесь, что вычисление
действительно тяжелое
21. Проблема: transferable взрывает мозг
var data = new ArrayBuffer(1024);
console.log(data);
// ArrayBuffer {byteLength: 1024}
postMessage(data, [data]);
console.log(data);
// null
25. Проблема: отсутствие тормозов
● Пользователь привык, что все
тормозит
● Программист привык, что страница
блокируется
Уведомите пользователя, что работа идет!