Slides from my talk at the Angular Community Days 2017 in Barcelona. In this keynote I talked about the JS single threaded nature, the problem WebWorkers solve, their basics, and the fancy Angular approach in order to bootstrap your whole app inside a WebWorker so the UI does not freeze when running CPU consuming tasks in your code.
5. ANGULAR WEB WORKERS 5
JS is async & Single threaded
import api from './controllers/api';
var login = (user, pwd) => {
api.post('login', {user:user, pwd:pwd})
.then(response => {
if(response.code == 200){
console.log("Congrats! you're in");
}
else{
console.log("Login error");
}
});
console.log("let's try to log-in");
}
Program thread
1
@Enrique_oriol
6. ANGULAR WEB WORKERS 6
import api from './controllers/api';
var login = (user, pwd) => {
api.post('login', {user:user, pwd:pwd})
.then(response => {
if(response.code == 200){
console.log("Congrats! you're in");
}
else{
console.log("Login error");
}
});
console.log("let's try to log-in");
}
JS is async & Single threaded
Program thread
1
Somewhere
else
A
S
Y
N
C
Waiting for
response
@Enrique_oriol
7. ANGULAR WEB WORKERS 7
import api from './controllers/api';
var login = (user, pwd) => {
api.post('login', {user:user, pwd:pwd})
.then(response => {
if(response.code == 200){
console.log("Congrats! you're in");
}
else{
console.log("Login error");
}
});
console.log("let's try to log-in");
}
JS is async & Single threaded
Program thread
1
Somewhere
else
A
S
Y
N
C
2
Waiting for
response
@Enrique_oriol
8. ANGULAR WEB WORKERS 9
JS is async & Single threaded
import api from './controllers/api';
var login = (user, pwd) => {
api.post('login', {user:user, pwd:pwd})
.then(response => {
if(response.code == 200){
console.log("Congrats! you're in");
}
else{
console.log("Login error");
}
});
console.log("let's try to log-in");
}
Program thread
Somewhere
else
1
2
3
A
S
Y
N
C
Waiting for
response
@Enrique_oriol
15. ANGULAR WEB WORKERS 16
WEB WORKERS
HTML5 compatible
INDEPENDENT
FILE
ISOLATED
PROCESS
MESSAGE BASED
COMMUNICATION
RUN TASKS IN
PARALLEL
@Enrique_oriol
16. ANGULAR WEB WORKERS 17
WEB WORKERS
The web worker
myWorker.js
var someVeryHardTask = param => {/*...some stuff*/}
self.addEventListener('message', e => {
let result = someVeryHardTask(e.data);
self.postMessage(result);
}, false);
@Enrique_oriol
17. ANGULAR WEB WORKERS 18
WEB WORKERS
The web worker
myWorker.js
var someVeryHardTask = param => {/*...some stuff*/}
self.addEventListener('message', e => {
let result = someVeryHardTask(e.data);
self.postMessage(result);
}, false);
@Enrique_oriol
18. ANGULAR WEB WORKERS 19
WEB WORKERS
The web worker
myWorker.js
var someVeryHardTask = param => {/*...some stuff*/}
self.addEventListener('message', e => {
let result = someVeryHardTask(e.data);
self.postMessage(result);
}, false);
@Enrique_oriol
19. ANGULAR WEB WORKERS 20
WEB WORKERS
The web worker
myWorker.js
var someVeryHardTask = param => {/*...some stuff*/}
self.addEventListener('message', e => {
let result = someVeryHardTask(e.data);
self.postMessage(result);
}, false);
@Enrique_oriol
20. ANGULAR WEB WORKERS 21
WEB WORKERS
The “main thread”
main.js
var worker = new Worker('myWorker.js');
worker.onmessage = event => {
console.log(result, event.data);
}
worker.postMessage("someData");
@Enrique_oriol
21. ANGULAR WEB WORKERS 22
WEB WORKERS
The “main thread”
main.js
var worker = new Worker('myWorker.js');
worker.onmessage = event => {
console.log(result, event.data);
}
worker.postMessage("someData");
@Enrique_oriol
22. ANGULAR WEB WORKERS 23
WEB WORKERS
The “main thread”
main.js
var worker = new Worker('myWorker.js');
worker.onmessage = event => {
console.log(result, event.data);
}
worker.postMessage("someData");
@Enrique_oriol
23. ANGULAR WEB WORKERS 24
WEB WORKERS
Thread 2 (myWorker.js)Thread 1 (main.js)
The big picture
var worker=new Worker('myWorker.js');
worker.postMessage("st");
console.log(result)
someVeryHardTask(e.data);
self.postMessage(result);
self.onmessage(...)self.onmessage(...)
@Enrique_oriol
24. ANGULAR WEB WORKERS 25
CAUTION
Is this enough?
This idea is extremely hot
@Enrique_oriol
25. ANGULAR WEB WORKERS 26
WEB WORKERS
● LOTS OF TASKS ?
○ INFINITE SWITCH STATEMENT?
○ SEVERAL WORKERS?
○ TOO MUCH MESSAGING STUFF…
● Heavy DOM?
● CONSUMING UI?
Is this enough ?
@Enrique_oriol
26. ANGULAR WEB WORKERS 27
WEB WORKERS
Native apps approach
DO NOT BLOCK THE UI THREAD
@Enrique_oriol
27. ANGULAR WEB WORKERS 28
WEB WORKERS
Native apps approach: do not block the UI thread
Other stuff threadsUI Thread (main thread)
@Enrique_oriol
29. ANGULAR WEB WORKERS 30
CAUTION
Why don’t we run
all the business logic of our app,
directly,
inside a web worker?
This idea is extremely hot
@Enrique_oriol
30. ANGULAR WEB WORKERS 31
CAUTION
COOL!
This idea is extremely hot
@Enrique_oriol
31. ANGULAR WEB WORKERS 32
CAUTION
But…
how does it work?
This idea is extremely hot
@Enrique_oriol
32. ANGULAR WEB WORKERS 33
REGULAR
Angular bootstrap
index.html
bundle.js
App component
bootstrapModule(AppModule)
Using platform-browser
<script></script>
@Enrique_oriol
33. ANGULAR WEB WORKERS 34
WEB WORKERS
Angular bootstrap
index.html
bundle.js
worker.js
bootstrapWorkerUI(‘worker.js’)
Using platform-webworker
<script></script>
App component
bootstrapModule(AppModule)
Using platform-worker
UI thread Worker thread
@Enrique_oriol
34. ANGULAR WEB WORKERS 35
WEB WORKERS
Angular approach (simplified) idea
Worker threadUI Thread
postMessage(“data”)
UI event (click, …)
postMessage(“call component method”)
Binded data updated
Run
business
logic
@Enrique_oriol
35. ANGULAR WEB WORKERS 36
WEB WORKERS
Angular approach
Worker threadUI Thread
postMessage(“data”)
UI event (click, …)
postMessage(“call component method”)
Binded data updated
Run
business
logic
Angular handles this for you
@Enrique_oriol
36. ANGULAR WEB WORKERS 37
BENEFITS
Running Angular with Web Workers
● Components remain the same
● Full access to Angular APIs
● Web Worker code can always run without Web Workers
@Enrique_oriol
37. ANGULAR WEB WORKERS 38
LIMITATIONS
Running Angular with Web Workers
● No DOM access
● DOM manipulation should be done by
○ Data bindings
○ Using Renderer
@Enrique_oriol
38. ANGULAR WEB WORKERS 39
LIMITATIONS
Where can you use Web Workers (April 2017)
@Enrique_oriol
40. ANGULAR WEB WORKERS 41
You can download code here:
https://github.com/kaikcreator/angular-cli-web-worker
And play it live here:
https://kaikcreator.github.io/angular-cli-web-worker/
EXAMPLE APP
Factorial app demo example
@Enrique_oriol
41. ANGULAR WEB WORKERS 42
CAUTION
You convinced me...
Can you guide me step-by-step?
This idea is extremely hot
@Enrique_oriol
42. ANGULAR WEB WORKERS 43
CAUTION
For sure!
Take any existing angular CLI
project and...
This idea is extremely hot
@Enrique_oriol
43. ANGULAR WEB WORKERS 44
Extract webpack file
@Enrique_oriol
MIGRATION GUIDE
From Angular CLI generated project
ng eject
npm installRun new dependencies generated by CLI
npm install --save @angular/platform-webworker @angular/platform-webworker-dynamic
Install webworker bootstrap dependencies
44. ANGULAR WEB WORKERS 45
Changes in app.module.ts
@Enrique_oriol
MIGRATION GUIDE
From Angular CLI generated project
BrowserModuleReplace
WorkerAppModulewith @angular/platform-webworkerfrom
45. ANGULAR WEB WORKERS 46
Changes in main.ts
@Enrique_oriol
MIGRATION GUIDE
From Angular CLI generated project
bootstrapModule()Replace
bootstrapWorkerUi(‘webworker.bundle.js’)
@angular/platform-webworkerfrom
with
46. ANGULAR WEB WORKERS 47
MIGRATION GUIDE
From Angular CLI generated project
Create file workerLoader.ts
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);
@Enrique_oriol
47. ANGULAR WEB WORKERS 48
Update webpack to build your webworker
@Enrique_oriol
MIGRATION GUIDE
From Angular CLI generated project
webworkerAdd entry point workerLoader.tsfor
Update HtmlWebpackPlugin to exclude webworker
Update CommonChunksPlugin inline chunk to prevent including webworker
‘entryModule’: ‘app/app.module#AppModule’Update AotPlugin with