Skip to content

Commit 40ba0ef

Browse files
committed
Added web workers demo
1 parent eade4a8 commit 40ba0ef

File tree

9 files changed

+3404
-0
lines changed

9 files changed

+3404
-0
lines changed

09 Web Workers/README.md

+221
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,221 @@
1+
## In this demo we are going to work with Web Workers.
2+
* Folder structure:
3+
4+
09 Web Workers/
5+
├── src/
6+
│ ├── content/
7+
| | ├── site.css
8+
│ ├── js/
9+
| | ├── inline.js
10+
| | ├── crunchNumbers.js
11+
| | ├── background.js
12+
│ ├── index.html
13+
│ └── bootstrap-theme.min.css
14+
├── gulpfile.js
15+
├── package.json
16+
17+
* Start from previous code demo.
18+
19+
## Steps.
20+
21+
### 1. Refactor the `index.html` for our demo.
22+
23+
* Just paste this code.
24+
25+
```diff html
26+
<!doctype html>
27+
28+
<html lang="en">
29+
<head>
30+
<meta charset="utf-8">
31+
<title>LEMONCODE 16/17 jQuery</title>
32+
<link rel="stylesheet" href="content/site.css">
33+
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
34+
</head>
35+
36+
<body>
37+
<h1>API Rest</h1>
38+
+ <!-- HTML5 element to show progress -->
39+
+ <progress id="worker-progress" value="0" max="100"></progress>
40+
</body>
41+
</html>
42+
43+
```
44+
45+
### 2. Lets change our `site.css`, for this demo.
46+
47+
```diff site.css
48+
@import url('https://fonts.googleapis.com/css?family=Raleway');
49+
50+
body {
51+
font-family: 'Raleway', sans-serif;
52+
}
53+
54+
.container {
55+
padding: 2em;
56+
}
57+
58+
.container p {
59+
max-width: 70%;
60+
font-size: 0.9em;
61+
margin-top: 0.2em;
62+
margin-bottom: 0.2em;
63+
height: 2.3em;
64+
}
65+
66+
.container p img {
67+
max-width: 95%;
68+
max-height: 95%;
69+
position: relative;
70+
top: 0.7em;
71+
left: 1em;
72+
}
73+
74+
.container ul {
75+
list-style: none;
76+
}
77+
78+
+progress {
79+
+ width: 80%;
80+
+ height: 20px;
81+
+ -webkit-appearance: none;
82+
+}
83+
+
84+
+progress::-webkit-progress-bar {
85+
+ background: lightgrey;
86+
+ border-radius: 50px;
87+
+ border: 1px solid gray;
88+
+}
89+
+
90+
+progress::-webkit-progress-value {
91+
+ background: #31C6F7;
92+
+ border-radius: 50px;
93+
+}
94+
+
95+
```
96+
### 3. Lets start by creating a new script and watch the effects on browser.
97+
98+
```diff index.html
99+
<!doctype html>
100+
101+
<html lang="en">
102+
<head>
103+
<meta charset="utf-8">
104+
<title>LEMONCODE 16/17 jQuery</title>
105+
<link rel="stylesheet" href="content/site.css">
106+
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
107+
</head>
108+
109+
<body>
110+
<h1>API Rest</h1>
111+
<!-- HTML5 element to show progress -->
112+
<progress id="worker-progress" value="0" max="100"></progress>
113+
114+
+ <script src="./js/inline.js"></script>
115+
</body>
116+
</html>
117+
118+
```
119+
120+
```javascript inline.js
121+
(() => {
122+
const longTask = (progressCalback) => {
123+
for (let step = 0; step < 10; step++) {
124+
progressCalback(step * 10);
125+
/*
126+
Use the developer tools to show that the console log is not blocked
127+
*/
128+
console.log(step);
129+
const start = Date.now();
130+
const seconds = 1;
131+
const waitUntil = start + seconds * 1000;
132+
while (Date.now() < waitUntil) {}
133+
}
134+
};
135+
136+
const progress = document.getElementById('worker-progress');
137+
138+
longTask((percentage) => {
139+
progress.value = percentage;
140+
});
141+
})();
142+
143+
144+
```
145+
* We have the element progress.
146+
* We have `longTask`, that will update the screen on its feed it `callback`.
147+
* `longTask` performances an intensive task blocking the UI around 1 second.
148+
* How many little programs are? -> `2`
149+
150+
> NOTE: Use developer tools to watch that the console does not get blocked.
151+
152+
* We can watch in `console.log(step)`, how it's getting updated when we get a new step value, but the UI it's not getting updated. This is because it's not to get updated until, the code block ends (`for statement`).
153+
154+
* Let's write this with a web worker to avoid this issue.
155+
156+
### 4. We have to create two new files in order to use a Web Worker.
157+
158+
```javascript longTask.js
159+
const longTask = (progressCalback) => {
160+
for (let step = 0; step < 10; step++) {
161+
progressCalback(step * 10);
162+
/*
163+
Use the developer tools to show that the console log is not blocked
164+
*/
165+
console.log(step);
166+
const start = Date.now();
167+
const seconds = 1;
168+
const waitUntil = start + seconds * 1000;
169+
while (Date.now() < waitUntil) {}
170+
}
171+
};
172+
173+
longTask(postMessage);
174+
175+
```
176+
177+
```javascript background.js
178+
(() => {
179+
const progress = document.getElementById('worker-progress');
180+
181+
const longTaskWorker = new Worker('./js/longTask.js');
182+
183+
longTaskWorker.onmessage = (message) => {
184+
progress.value = message.data;
185+
};
186+
})();
187+
```
188+
189+
* `longTask(postMessage);` El callback que le pasamos es un método del propio worker (el worker inyecta el callback) que al ser invocado el statement: `progressCallback(step * 10);` manda el mensaje, que recibe el worker `worker.onmessage`. La comunicación puede ser bidireccional.
190+
191+
* NOTA: NO tiene acceso al DOM.
192+
193+
### REFERENCE https://developer.mozilla.org/es/docs/Web/Guide/Performance/Usando_web_workers
194+
195+
* Now we can change `index.html`, to watch results.
196+
197+
```diff index.html
198+
<!doctype html>
199+
200+
<html lang="en">
201+
<head>
202+
<meta charset="utf-8">
203+
<title>LEMONCODE 16/17 jQuery</title>
204+
<link rel="stylesheet" href="content/site.css">
205+
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
206+
</head>
207+
208+
<body>
209+
<h1>API Rest</h1>
210+
<!-- HTML5 element to show progress -->
211+
<progress id="worker-progress" value="0" max="100"></progress>
212+
213+
+ <script src="./js/background.js"></script>
214+
- <script src="./js/inline.js"></script>
215+
</body>
216+
</html>
217+
218+
```
219+
* En conclusión, uando el web worker se ejecuta, crunchNumbers es llamado, postMessage es la función que se usa para mandar mensajesal principal, el engine de JavaScript que controla la UI.
220+
* Este ejemplo de IPC, en realidad no lo es. Este web workerque hemos creado con new, es un web worker dedicado, sólo es un thread que se ejecuta dentro del mismo proceso, pero aún así tenemos cierta separación entre la ejecución del JavaScript que esta ejcutando estos workers.
221+
* Existe una asincronicidad debido a la separación de hilos. Los shared workers, si ejecutan sus propios procesos, y son un ejemplo claro de IPC.

09 Web Workers/gulpfile.js

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
'use strict';
2+
3+
const gulp = require('gulp'),
4+
connect = require('gulp-connect'),
5+
open = require('gulp-open'),
6+
options = {
7+
port: 9005,
8+
root: ['src'],
9+
devBase: 'http://localhost:',
10+
browsers: ['safari', 'chrome']
11+
},
12+
openOptions = {
13+
uri: options.devBase + options.port,
14+
app: options.browser
15+
};
16+
17+
gulp.task('connect', () => connect.server({
18+
root: options.root,
19+
port: options.port
20+
}));
21+
// https://github.com/stevelacy/gulp-open/issues/15
22+
gulp.task('open', () => gulp.src(__filename).pipe(open(openOptions)));
23+
24+
gulp.task('default', ['connect', 'open']);

0 commit comments

Comments
 (0)