Slide 1

Slide 1 text

Off-the-main-thread with WorkerDOM Kyoto.js #15 ฏ໺ ণ࢜(@shisama)

Slide 2

Slide 2 text

ฏ໺ ণ࢜ / Masashi Hirano ɹɹɹɹ Kyoto office @shisama_ @shisama Node.js Core Collaborator ؔ੢NodeֶԂOrganizer

Slide 3

Slide 3 text

αΠϘ΢ζେࡕΦϑΟε കాࡕٸΦϑΟεϏϧ

Slide 4

Slide 4 text

஫ҙ ࠓճग़ͯ͘Δ࿩͸ ·ͩٞ࿦தͷ಺༰΋ ؚ·Ε͍ͯ·͢

Slide 5

Slide 5 text

Agenda • Performance • off-the-main-thread • WebWorker • WorkerDOM (+ React)

Slide 6

Slide 6 text

Performance

Slide 7

Slide 7 text

Performance • ͦ΋ͦ΋Web͸ૣ͍ • ଟػೳ΍ϦονͳUIΛఏڙ͢Δ͔Β஗͘ͳΔ • ஗͘ͳΔͷʹ΋༷ʑͳཁҼ͕͋Δ
 ɾωοτϫʔΫ
 ɾϨϯμϦϯά
 ɾJavaScript etc…

Slide 8

Slide 8 text

Performance • ωοτϫʔΫͷ໰୊͸վળ͞Ε͖ͯͨ
 ɾϦΫΤετճ਺ͷ࡟ݮ
 ɾCache
 ɾHTTP/2 etc… • JavaScriptͷ࣮ߦ΍ϨϯμϦϯά͕ϘτϧωοΫʹͳ͖ͬͯͨ • ࠷ۙ͸ϑϩϯτΤϯυͰCPUϔϏʔͳॲཧ͕࣮ߦ͞ΕΔ

Slide 9

Slide 9 text

ϝΠϯεϨουͰscripting΍rendering͕ ߦΘΕ͍ͯΔ

Slide 10

Slide 10 text

ChromeͷAudits(Lighthouse)Ͱ PerformanceΛܭଌ͢ΔͱϝΠϯεϨουͷ JSͷॲཧΛݮΒ͢Α͏ʹڭ͑ͯ͘ΕΔ

Slide 11

Slide 11 text

off-the-main-thread

Slide 12

Slide 12 text

off-the-main-threadͱ͸ • ϝΠϯεϨουͱ͸ผεϨουʹॲཧΛҕৡ͢Δ͜ͱ • ϝΠϯεϨουΛઐ༗͢ΔͱUI΍ϢʔβʔΠϯλϥΫγϣϯͷॲ ཧ͕ϒϩοΫ͞ΕΔ • 16msҎ্ϝΠϯεϨουΛࢭΊͪΌμϝ

Slide 13

Slide 13 text

6TFS*OUFSBDUJPO 'FFECBDL )FBWZ5BTL ϝΠϯεϨουΛઐ༗ UIʹϥά͕ੜ͡Δ ΧΫ͖ͭɾ΋͖ͨͭΛײ͡Δ

Slide 14

Slide 14 text

$BMM )FBWZ 5BTL 3FTQPOTF 'FFECBDL 6TFS*OUFSBDUJPO 'FFECBDL .BJO5ISFBE 0UIFS5ISFBE

Slide 15

Slide 15 text

)FBWZ 5BTL 'FFECBDL 6TFS*OUFSBDUJPO 'FFECBDL $BMM 3FTQPOTF .BJO5ISFBE 0UIFS5ISFBE Ͳ͏΍ͬͯ΍Δ…?

Slide 16

Slide 16 text

WebWorker

Slide 17

Slide 17 text

https://developer.mozilla.org/ja/docs/Web/API/Web_Workers_API

Slide 18

Slide 18 text

https://caniuse.com/#feat=webworkers

Slide 19

Slide 19 text

https://github.com/nodejs/node/pull/25361

Slide 20

Slide 20 text

WebWorkerͱ͸ • JavaScriptͰ΋ϚϧνεϨου͕࢖༻Մೳ • Worker༻ͷJSϑΝΠϧΛ༻ҙͯ͠WorkerεϨουͰ࣮ߦ • ͓ޓ͍ͷεϨου͸ಠཱͨ͠ϝϞϦྖҬΛ֬อ͍ͯ͠Δ
 ɾεϨουA͔ΒεϨουBͷ஋ʹ͸ΞΫηεͰ͖ͳ͍
 ɾεϨουؒ͸ϝοηʔδύογϯάͰσʔλΛ΍ΓऔΓ͢Δ

Slide 21

Slide 21 text

// workerͰ࣮ߦ͢ΔϑΝΠϧΛࢦఆ͠workerੜ੒ const worker = new Worker(“./worker.js"); // workerʹσʔλΛ౉͢ worker.postMessage(time); // workerଆ͔ΒσʔλΛड͚औͬͨͱ͖ worker.onmessage = (e) => { const el = document.createElement('div'); el.textContent = e.data; document.body.appendChild(el); } εϨουؒͷσʔλڞ༗ // ϝΠϯεϨου͔ΒσʔλΛड͚औͬͨͱ͖ onmessage = (e) => { const n = e.data; for (let i = 0; i <= n; i++) { // Կ͔ॏ͍ॲཧ // ॲཧ݁ՌΛϝΠϯεϨουʹ౉͢ postMessage(result); } } ϝΠϯεϨου Worker༻ϑΝΠϧ

Slide 22

Slide 22 text

http://nerget.com/rayjs-mt/rayjs.html ը૾ॲཧͰൺֱ ࠨ: Workerͳ͠ 1.647s ӈ: 4ͭͷWorker 0.765

Slide 23

Slide 23 text

WebWorkerͷ՝୊ • postMessage͸ϝϞϦͷڞ༗Ͱ͸ͳ͘ίϐʔΛ౉͍ͯ͠Δ
 • postMessage࢖͍ͮΒ͘ͳ͍…?
 • Worker಺ͰDOMૢ࡞͕Ͱ͖ͳ͍

Slide 24

Slide 24 text

WebWorkerͷ՝୊ • postMessage͸ϝϞϦͷڞ༗Ͱ͸ͳ͘ίϐʔΛ౉͍ͯ͠Δ
 SharedArrayBufferͱAtomics APIΛ࢖͏ • postMessage࢖͍ͮΒ͘ͳ͍…?
 Comlink΍ClooneyΛ࢖͏ • Worker಺ͰDOMૢ࡞͕Ͱ͖ͳ͍
 WorkerDOMΛ࢖͏

Slide 25

Slide 25 text

WebWorkerͷ՝୊ • postMessage͸ϝϞϦͷڞ༗Ͱ͸ͳ͘ίϐʔ
 SharedArrayBufferͱAtomics APIΛ࢖͏ • postMessage࢖͍ͮΒ͘ͳ͍…?
 Comlink΍ClooneyΛ࢖͏ • Worker಺ͰDOMૢ࡞͕Ͱ͖ͳ͍
 WorkerDOMΛ࢖͏

Slide 26

Slide 26 text

http://2ality.com/2017/01/shared-array-buffer.html ࢀߟ: SharedArrayBufferͱAtomics API https://qiita.com/yosuke_furukawa/items/923f8d40c451713dfbd3

Slide 27

Slide 27 text

https://github.com/GoogleChromeLabs/comlink ࢀߟ: Comlink

Slide 28

Slide 28 text

https://github.com/GoogleChromeLabs/clooney ࢀߟ: Clooney

Slide 29

Slide 29 text

WorkerDOM

Slide 30

Slide 30 text

https://github.com/ampproject/worker-dom

Slide 31

Slide 31 text

WorkerDOMͱ͸ • WebWorkerͰDOMૢ࡞Λߦ͏ͨΊͷϥΠϒϥϦ • AMP(Accelerated Mobile Pages)ϓϩδΣΫτ͕։ൃ • ·ͩalpha൛

Slide 32

Slide 32 text

WorkerDOM࢖͍ํ • npm
 npm install @ampproject/worker-dom • CDN
 https://unpkg.com/@ampproject/[email protected]

Slide 33

Slide 33 text

import {upgradeElement} from ‘/path/to/index.mjs’; upgradeElement(document.getElementById(‘upgrade-me'), ‘/path/to/worker.mjs’); WorkerDOM࢖͍ํ for (let i = 0; i <= n; i++) { // Կ͔ॏ͍ॲཧ // ॲཧ݁ՌΛϝΠϯεϨουʹ౉͢ const el = document.createElement('div'); el.textContent = result; document.body.appendChild(el); } HTML (ϝΠϯεϨου) : Worker༻ϑΝΠϧ :

Slide 34

Slide 34 text

import {upgradeElement} from ‘/path/to/index.mjs’; upgradeElement(document.getElementById(‘upgrade-me'), ‘/path/to/worker.mjs’); WorkerDOM࢖͍ํ 1. WorkerଆͰ࣮ߦ͢ΔϑΝΠϧΛࢦఆ 2. worker-domͷindex.mjs͔ΒupgradeElementؔ਺Λimport 3. 1ͷDOMͱworker-domͷworker.mjsΛҾ਺ʹઃఆ࣮͠ߦ

Slide 35

Slide 35 text

WorkerDOMͰԿ͕Ͱ͖Δͷ͔ • ͢΂ͯͷॲཧΛWorkerଆʹҕৡ͢Δ͜ͱ͕Ͱ͖Δ͔΋ • AMPͰ΋೚ҙͷJavaScriptΛ࣮ߦͰ͖Δ͔΋
 ɾamp-script͸಺෦ͰWorkerDOMΛ࢖͍ͬͯΔ • React΍VueͳͲ΋Worker಺Ͱ࣮ߦ͢Δ͜ͱ͕Ͱ͖Δ
 ɾampproject/worker-domʹ͸preactΛಈ͔͢σϞ͕͋Δ
 ɾWorkerDOM + React ࢼͯ͠Έͨ


Slide 36

Slide 36 text

import {upgradeElement} from '/dist/index.mjs'; upgradeElement(document.getElementById(‘hello’), '/dist/worker.mjs'); WorkerDOM + React const App = () => { return

Hello, World!

; }; ReactDOM.render(, document.getElementById('root')); HTML (ϝΠϯεϨου) : Worker༻ϑΝΠϧ :

Slide 37

Slide 37 text

import {upgradeElement} from '/dist/index.mjs'; upgradeElement(document.getElementById(‘hello’), '/dist/worker.mjs'); WorkerDOM + React const App = () => { return

Hello, World!

; }; ReactDOM.render(, document.getElementById('root')); HTML (ϝΠϯεϨου) : Worker༻ϑΝΠϧ : Workerଆ͔ΒΞΫηε͍ͨ͠DOM͸ upgradeElementͰࢦఆ͢ΔDOMͷதʹॻ͘

Slide 38

Slide 38 text

https://shisama.github.io/worker-dom-sample/react-app/ create-react-app

Slide 39

Slide 39 text

https://shisama.github.io/worker-dom-sample/react-app/ WorkerεϨουͰ࣮ߦ͞Ε͍ͯΔ͔֬ೝ

Slide 40

Slide 40 text

https://shisama.github.io/worker-dom-sample/react-app/ WorkerεϨουͰ࣮ߦ͞Ε͍ͯΔ͔֬ೝ

Slide 41

Slide 41 text

preact demo@ampproject/worker-dom https://github.com/ampproject/worker-dom/tree/master/demo/preact-dbmon

Slide 42

Slide 42 text

·ͱΊ • ϝΠϯεϨουͰϔϏʔͳॲཧΛ͍ͯ͠ͳ͍͔֬ೝ͠Α͏ • WebWorkerͰϔϏʔͳॲཧΛϝΠϯεϨου͔Βಀ͕ͦ͏ • WorkerDOMΛ࢖͏ͱWebWorkerͰ΋DOMૢ࡞͕ՄೳʹͳΔ • ReactͳͲ΋Worker಺Ͱ࣮ߦ͢Δ͜ͱ͕Ͱ͖Δ

Slide 43

Slide 43 text

ࢀߟ • ΢Σϒϒϥ΢βͷ off-the-main-thread API ͷ࿩ (@nhiroki) • Off the main thread with workers ! - Speaker Deck (@kosamari) • off-the-main-thread ͷ࣌୅ (@mizchi) • Off the main threadͷ࿩ - Speaker Deck (@yosuke_furukawa) • Web WorkersΛ༻͍ͯJavaScriptΛϚϧνεϨουԽ͢Δ (@kfurumiya)

Slide 44

Slide 44 text

Thanks.