
Web Workers
Добавьте производительности своим Web приложениям
Сергей Мелашич
Agilie
Сергей
Мелашич
web разработчик компании Agilie
SergeyMell
Seroga.Mell
Sergey Melashych
sergey.mell@agilie.com
преподаватель school.agilie.com
Мы живем во многопоточном мире






World
Software
JavaScript
Мир JavaScript
Мир JavaScript
CORE
CORE
CORE
CORE

Мир JavaScript
 api.post('/login', userData)
   .then(response => {
     // Success stuff
   }, error => {
     // Error stuff
   });
 // Other stuffAPP THREAD
Action 1
Action 2
Action 3
Waiting for the response
Проблема однопоточности
CORE
CORE
CORE
CORE

Рендеринг чуть подробнее

Сколько времени у нас есть?
60 fps
16 ms
8 - 10 ms
"Тяжелые" операции
Обработка больших структур данных
Обработка изображений / звука
Генерация больших таблиц
Визуализация данных
...
Пример "тяжелой" операции

Решение?



1. setTimeout
2. iframe
3. Web Worker
Поддержка браузерами


Особенности Web Workers
1. Хранится в отдельном файле и запускается
как отдельный процесс
if (window.Worker) {
  const myWorker = new Worker("hard_worker.js");
}2. Взаимодействие осуществляется посредством сообщений
myWorker.postMessage(data);
myWorker.onmessage = (event) => {
  console.log(event.data);
};Особенности Web Workers
3. Нет доступа к DOM
4. Нет доступа к document, window, parent
5. Глобальный контекст доступен посредством self
Многопоточное исполнение
APP THREAD
WORKER THREAD
const myWorker = 
  new Worker("hard_worker.js");myWorker.onmessage = ...myWorker.postMessage(...);renderResults(event.data);self.onmessage = ...;const result = 
  hardWork(event.data);self.postMessage(result);Блокировка рендеринга с решением

Shared Worker

const sharedWorker = new SharedWorker("shared.js");
sharedWorker.port.addEventListener("message", event => {
  // Subscribing Event
}, false);
sharedWorker.port.start();
sharedWorker.port.postMessage(data);Передача данных в Web Worker
1. Структурное клонирование (structured cloning)
myWorker.postMessage(arrayOfData);2. Передаваемые объекты (transferable objects)
myWorker.postMessage(arrayOfData, [arrayOfData]);3. Широковещательный канал (broadcast channel)
let channel = new BroadcastChannel('channel-name');
channel.postMessage(data);4. Общая память (shared memory)
const sharedBuffer = new SharedArrayBuffer(40);
myWorker.postMessage(sharedBuffer);Библиотеки для работы
с Web Workers

Parallel.js

Hamsters.js

Web Workers во фреймворках



Web Workers во Vue.js

this.$worker.run((arg) => {
  return `Hello, ${arg}!`;
}, ['World'])
  .then(result => {
    console.log(result);
  })
  .catch(e => {
    console.error(e);
  });https://github.com/israelss/vue-worker
Web Workers в React.js
https://github.com/web-perf/react-worker-dom


number of nodes
fps
react-renderer
react-worker-dom

Web Workers в Angular
UI THREAD
WORKER THREAD
Бизнес
логика
Пользовательское событие
postMessage('call');Связанные данные
postMessage(data);Как это сделать?
import '../polyfills.ts';
import '@angular/core';
import '@angular/common';
import {platformWorkerAppDynamic} from '@angular/platform-webworker-dynamic';
import { AppModule } from '../app/app.module';
platformWorkerAppDynamic().bootstrapModule(AppModule);bootstrapWorkerUi('../webworker.bundle.js');import { WorkerAppModule } from '@angular/platform-webworker';webworker.ts
main.ts
app.module.ts
Angular на  стероидах  WebWorker-ах
А как же роутинг?
@NgModule({
    ...,
    providers: [
        ...,
        {provide: APP_BASE_HREF, useValue: '/'},
        WORKER_APP_LOCATION_PROVIDERS,
    ]
});app.module.ts
bootstrapWorkerUi(
    '../webworker.bundle.js',
    WORKER_UI_LOCATION_PROVIDERS
);main.ts
Тестирование производительности
fps
интенсивность мутаций

Angular clean
Angular worker
Полезные ссылки
Благодарю за внимание
Пожалуйста, разбудите спящих соседей
SergeyMell
Seroga.Mell
Sergey Melashych
sergey.mell@agilie.com
fwdays 2018
By Sergey Mell
fwdays 2018
- 2,343
 
   
   
  