Slide 1

Slide 1 text

off the main thread ͷ࿩ 2018/06/26 @Lob inc

Slide 2

Slide 2 text

Twitter: @yosuke_furukawa Github: yosuke-furukawa

Slide 3

Slide 3 text

2018/11/23 - 24 Node ֶԂࡇ։࠵ https://bit.ly/nodefest2018

Slide 4

Slide 4 text

ϑϩϯτΤϯυνʔϜ͔Β8FC8PSLFSͷ ۙگ౳ʑʹ͍ͭͯฉ͖͍ͨͬͯϦΫΤετ͕ ͋Γ·͢Ͷɻ

Slide 5

Slide 5 text

ʊਓਓਓਓਓਓਓਓਓʊ ʼɹಥવͷWorkerͷ࿩ɹʻ ʉY^Y^Y^Y^Y^Y^Yʉ

Slide 6

Slide 6 text

WebWorkerΛ͍͖ͳΓ੾Γ औͬͯ΋ઌ୺ͷ࿩͗͢͠Δ 8PSLFSͷ࿩͸ࠓͷύϑΥʔ Ϛϯεͷಥ୺

Slide 7

Slide 7 text

WebWorkerΛ͍͖ͳΓ੾Γ औͬͯ΋ઌ୺ͷ࿩͗͢͠Δ ຒ·͍ͬͯΔ͜ͷ෦෼ͷ࿩ Λઌʹͯ͠ɺͦΕ͔Β 8PSLFSͷ࿩Λɻ

Slide 8

Slide 8 text

Web Performance 
 2000 - 2017

Slide 9

Slide 9 text

Performance Bible ~200X

Slide 10

Slide 10 text

Performance Bible ~200X

Slide 11

Slide 11 text

Performance Bible ~200X )551ϦΫΤετΛ࠷খݶʹ͠Α͏ $%/Λ࢖͓͏ $BDIF$POUSPMΛ࢖͓͏FUD Ϣʔβʔ͸ϑϩϯτΤϯυͰ 80 ~ 90% ͷ࣌ؒ଴ػ͍ͯ͠Δ

Slide 12

Slide 12 text

Previous Web Applications

Slide 13

Slide 13 text

Web Performance ~200X • Measuring Time from Request to Response

Slide 14

Slide 14 text

• Page Speed Insights • Apache Bench • jmeter 3FRTTFD ඵؒͰԿճϦΫΤετΛ͞͹͚͔ͨ USBOTGFSTFD ඵؒͰԿ#ZUFΛૹΕ͔ͨ -BUFODZ ߦ͔ͬͯΒฦͬͯ͘Δ·Ͱͷ࣌ؒ Web Performance Tools ~200X

Slide 15

Slide 15 text

Web Performance ~ 200X • ΍Δ͜ͱ • ϦΫΤετճ਺ͷվળ • Ϩεϙϯε͢ΔόΠτ਺ͷվળ

Slide 16

Slide 16 text

ϦΫΤετճ਺ͷվળ • αΠτΛߴ଎ʹ͢ΔҰ൪ͷํ๏͸
 ͦ΋ͦ΋ϦΫΤετ͠ͳ͍͜ͱ • ۃྗϦΫΤετ਺ΛݮΒ͢ • ex: CSSΛ1ϑΝΠϧʹɺJS΋ಉ༷ɻ

Slide 17

Slide 17 text

ϦΫΤετճ਺ͷվળ • CSS Sprite • Inline ల։ • Cache Control

Slide 18

Slide 18 text

• CSS Sprite • Inline ల։ • Cache Control ϦΫΤετճ਺ͷվળ $BDIF$POUSPM BTTFU͸%-ͨ͠ΒΩϟογϡͤ͞Δ $444QSJUF JDPO͸Ұͭʹ·ͱΊΔ *OMJOFల։ ͻͱ໨ݟͯग़ͯ͘ΔྖҬ͸$44ΛΠϯ ϥΠϯʹల։͢Δ

Slide 19

Slide 19 text

• CSS Sprite • Inline ల։ • Cache Control ϦΫΤετճ਺ͷվળ $BDIF$POUSPM BTTFU͸%-ͨ͠ΒΩϟογϡͤ͞Δ $444QSJUF JDPO͸Ұͭʹ·ͱΊΔ *OMJOFల։ ͻͱ໨ݟͯग़ͯ͘ΔྖҬ͸$44ΛΠϯ ϥΠϯʹల։͢Δ ͳΔ΂͘ϦΫΤετ͠ͳ͍

Slide 20

Slide 20 text

Ϩεϙϯε͢ΔόΠτ਺ͷվળ • ద੾ͳը૾ϑΥʔϚοτͷબ୒ɺϦαΠζ • imagemagick, AWS Lambda • webp, png, gif, jpeg • JS, css ͷ minify, gzipԽ

Slide 21

Slide 21 text

Ϩεϙϯε͢ΔόΠτ਺ͷվળ • ద੾ͳը૾ϑΥʔϚοτͷબ୒ɺϦαΠζ • imagemagick, AWS Lambda • webp, png, gif, jpeg • JS, css ͷ minify, gzipԽ ద੾ͳը૾ϑΥʔϚοτͷબ୒ TDSJQU΍TUZMF͸NJOJGZͯ͠H[JQʹ͢Δ ͜ͱͰখͯ͘͞͠഑৴

Slide 22

Slide 22 text

Ϩεϙϯε͢ΔόΠτ਺ͷվળ • ద੾ͳը૾ϑΥʔϚοτͷબ୒ɺϦαΠζ • imagemagick, AWS Lambda • webp, png, gif, jpeg • JS, css ͷ minify, gzipԽ ద੾ͳը૾ϑΥʔϚοτͷબ୒ TDSJQU΍TUZMF͸NJOJGZͯ͠H[JQʹ͢Δ ͜ͱͰখͯ͘͞͠഑৴ Ϩεϙϯε͢ΔόΠτ਺͕ݮΕ͹ଳ Ҭͷѹഭ͕ݮΔɺ࣌ؒ΋গͳ͘ͳΔ

Slide 23

Slide 23 text

Web Performance 2010-2016

Slide 24

Slide 24 text

Performance Bible 2010-2016

Slide 25

Slide 25 text

Performance Bible 2010-2016

Slide 26

Slide 26 text

Performance Bible 2010-2016 ॲཧͷத৺͕αʔό͔Βϒϥ΢β΁ ϨΠςϯγΛখ͘͞ɻ

Slide 27

Slide 27 text

Web Performance ~ 201X • ΍Δ͜ͱ • ϨΠςϯγΛԼ͛Δ • HTTPͷ௨৴ίετΛԼ͛Δ • ෦෼ϨϯμϦϯά͢Δ

Slide 28

Slide 28 text

HTTPͷ௨৴ίετΛԼ͛Δ • 1ͭͷHTTP઀ଓΛແବʹ͠ͳ͍ • ຖճHTTP઀ଓ͢Δͷ͸ωοτϫʔΫϨΠϠͰݟΔ ͱίετ͕ߴ͍ • 1ͭͷHTTP઀ଓͷதͰϦΫΤετΛଟॏԽ͢Δ • ઀ଓͬ͠ͺͳ͠ʹͳΔ͜ͱͰೖΕΒΕΔ࠷దԽ΋͋ ΔʢH2 Push, etcʣ

Slide 29

Slide 29 text

HTTPͷ௨৴ίετΛԼ͛Δ • 1ͭͷHTTP઀ଓΛແବʹ͠ͳ͍ • ຖճHTTP઀ଓ͢Δͷ͸ωοτϫʔΫϨΠϠͰݟΔ ͱίετ͕ߴ͍ • 1ͭͷHTTP઀ଓͷதͰϦΫΤετΛଟॏԽ͢Δ • ઀ଓͬ͠ͺͳ͠ʹͳΔ͜ͱͰೖΕΒΕΔ࠷దԽ΋ ͋Δʢޙड़ʣ )551

Slide 30

Slide 30 text

HTTP2 • ଟॏԽ͞ΕͨϦΫΤετΛૹΔ • HTTP/1.1 ࣌୅ΑΓ΋1ͭͷωοτϫʔΫ઀ଓ Λ࢖ͬͨ࠷దԽ͕ߦΘΕΔΑ͏ʹɻ • Prioritization, Server Push, Early Hints ଳҬ෯͕૿͑ͯ΋ϨΠςϯγ͕ݮΒͳ ͍ͱࠓޙͷߴ଎Խ͕Ͱ͖ͳ͍

Slide 31

Slide 31 text

෦෼ϨϯμϦϯά͢Δ • Ajax ௨৴Λجຊͱͯ͠෦෼ϨϯμϦϯάΛ͢ Δ͜ͱͰߴ଎Խ͢Δํ๏

Slide 32

Slide 32 text

෦෼ϨϯμϦϯά͢Δ • Ajax ௨৴Λجຊͱͯ͠෦෼ϨϯμϦϯάΛ͢ Δ͜ͱͰߴ଎Խ͢Δํ๏ DMJDL

Slide 33

Slide 33 text

෦෼ϨϯμϦϯά͢Δ • Ajax ௨৴Λجຊͱͯ͠෦෼ϨϯμϦϯάΛ͢ Δ͜ͱͰߴ଎Խ͢Δํ๏ DMJDL (&5+40/

Slide 34

Slide 34 text

෦෼ϨϯμϦϯά͢Δ • Ajax ௨৴Λجຊͱͯ͠෦෼ϨϯμϦϯάΛ͢ Δ͜ͱͰߴ଎Խ͢Δํ๏ DMJDL (&5+40/ 1BSUJBM3FOEFS

Slide 35

Slide 35 text

෦෼ϨϯμϦϯά͢Δ • Ajax ௨৴Λجຊͱͯ͠෦෼ϨϯμϦϯάΛ͢ Δ͜ͱͰߴ଎Խ͢Δํ๏ DMJDL (&5+40/ 1BSUJBM3FOEFS 3JDIͳ8FC"QQMJDBUJPO͸େମ͜ ͏ͳ͖͍ͬͯͯΔɻ

Slide 36

Slide 36 text

Web Performance ~2016 • Network Optimization • HTTP/2 • Single Page Application • Partial Rendering • Ajax

Slide 37

Slide 37 text

͜Ε·ͰͷύϑΥʔϚϯεͷ γϣʔτ·ͱΊ • ϘτϧωοΫ͸ωοτϫʔΫͱදࣔॲཧ • ϦΫΤετ਺Λվળ • ϨεϙϯεͷόΠταΠζΛվળ • ϨΠςϯγΛվળ • ࠩ෼ϨϯμϦϯάʹΑͬͯදࣔޮ཰Խ΋࣮ࢪ

Slide 38

Slide 38 text

͜Ε·ͰͷύϑΥʔϚϯεͷ γϣʔτ·ͱΊ • ϘτϧωοΫ͸ωοτϫʔΫͱදࣔॲཧ • ϦΫΤετ਺Λվળ • ϨεϙϯεͷόΠταΠζΛվળ • ϨΠςϯγΛվળ • ࠩ෼ϨϯμϦϯάʹΑͬͯදࣔޮ཰Խ΋࣮ࢪ վળϙΠϯτ͕ʰϦΫΤετ͔ͯ͠Βදࣔ͞ΕΔ·Ͱʱɺ͔Β ʰදࣔޙͷૢ࡞Ͱ͖Δ·ͰʱʹਪҠ͖͍ͯͯ͠Δ

Slide 39

Slide 39 text

Off the Main Thread ͷ࿩ • ʰϖʔδ͕දࣔ͞ΕΔ·Ͱʱͷվળ͸͜Ε· Ͱ΋͜Ε͔Β΋࣮ࢪத • ʰૢ࡞Ͱ͖ΔΑ͏ʹͳΔʱ·ͨ͸ʰૢ࡞͕ޮ ཰తʹͳΔʱվળ͕ࠓޙͷΩʔʹͳΔɻ • ʰOff the Main Threadʱ ͸͜ͷվળͷҰͭͷ ςʔϚ

Slide 40

Slide 40 text

ͦ΋ͦ΋First ViewͱҰޱʹ ݴͬͯ΋छྨ͕͋Δ /BWJHBUJPO4UBSU 'JSTU1BJOU 'JSTU$POUFOUGVM 1BJOU Loading.. 'JSTU.FBOJOHGVM 1BJOU 'JSTU.FBOJOHGVM 1BJOU 7JTVBMMZSFBEZ *NBHF 5JNF5P *OUFSBDUJWF +4MPBEFE *NBHF 'VMMZ-PBEFE BMMSFTPVSDFTBSF MPBEFE *NBHF

Slide 41

Slide 41 text

ͦ΋ͦ΋First ViewͱҰޱʹ ݴͬͯ΋छྨ͕͋Δ /BWJHBUJPO4UBSU 'JSTU1BJOU 'JSTU$POUFOUGVM 1BJOU Loading.. 'JSTU.FBOJOHGVM 1BJOU 7JTVBMMZSFBEZ *NBHF 5JNF5P*OUFSBDUJWF *NBHF 'VMMZ-PBEFE *NBHF දࣔͯ͠ಡΊΔΑ͏ʹͳΔ·Ͱ ૢ࡞Ͱ͖ΔΑ͏ʹͳΔ·Ͱ ૢ࡞த

Slide 42

Slide 42 text

Off the Main Thread ͱ͸ • Main Thread ͰͷॲཧΛۃྗখ͘͞Ͱ͖ΔΑ͏ʹ͍ͯ͠ ͜͏ͱ͍͏ࢼΈʢ·ͩԿ͔݁࿦͕ग़ͯΔΘ͚Ͱ͸ͳ͍ʣ • Main Threadͷॲཧ͕ॏ͘ͳΔͱUI Jankͱݺ͹ΕΔʰΧ ΫπΩɾΨλπΩɾҰݟಈ͍ͯͳ͍͔ͷΑ͏ʹݟ͑Δো ֐ʱ͕ൃੜ͢Δ • Main Thread ͔Β Worker Thread Λ͏·͘࢖͑ΔΑ͏ ʹɺͱ͍͏ͷ͕τϐοΫͷҰͭɻ

Slide 43

Slide 43 text

Off the Main Thread • ϒϥ΢β͔Β΋main thread͕ࢥ͍ͱೖྗͰ͖ Δͷ͕஗͘ͳͬͨΓɺεΫϩʔϧ͕Ψλ͍ͭ ͨΓ͢Δ https://docs.google.com/presentation/d/1OBij2sz6gNU-VCrNz7REvJ4piiM21YZnVCUnl6MjUas/ edit#slide=id.g372bf772fc_0_55

Slide 44

Slide 44 text

ChromeͷऔΓ૊Έ • lighthouse Ͱ͸ main thread ͷॲཧ͕ॏ͍ͱ ܯࠂ͕ग़ΔʢϝτϦΫεΛվળʣɻ • ࣮ࡍʹPerformance Tab ͷத͔Βಛఆ͢Δ͜ ͱ΋Մೳ

Slide 45

Slide 45 text

ChromeͷऔΓ૊Έ • PerformanceObserver ͔Β LongTask (50ms Ҏ্͔͔Δtask)Λ؂ࢹͰ͖ΔΑ͏ʹɻ var observer = new PerformanceObserver(function(list) { var perfEntries = list.getEntries(); for (var i = 0; i < perfEntries.length; i++) { // LongTaskͷ࣮ߦதͰ͋Δ͜ͱΛ௨஌ // ௨஌ͨ͠Βϩάʹॻ͘ͳͲͷղੳʹ׆͔͢ } }); // long task Λ؍ଌՄೳʹɻ observer.observe({entryTypes: ["longtask"]}); https://github.com/w3c/longtasks

Slide 46

Slide 46 text

ChromeͷऔΓ૊Έ • Worker APIΛΑΓ࢖͍΍͘͢͢Δٞ࿦͕͋Δ https://drive.google.com/file/d/ 18V0baK57sAUFtD6uO9neLtZY8pR-Fzvn/view

Slide 47

Slide 47 text

• Worker API: 
 ࠓ͸ϝοηʔδύογϯάʹΑΔڠௐϞσϧ WebWorker // main.js var worker = new Worker('worker.js'); worker.addEventListener('message',(e) => { // message ड৴ console.log('Worker send: ', e.data); }); // messageૹ৴ worker.postMessage('Hello World'); // worker.js self.addEventListener('message',(e) => { // message ड৴ console.log('Main send:', e.data); // message ૹ৴ self.postMessage(e.data); });

Slide 48

Slide 48 text

• Worker API: 
 ࠓ͸ϝοηʔδύογϯάʹΑΔڠௐϞσϧ WebWorker // main.js var worker = new Worker('worker.js'); worker.addEventListener('message',(e) => { // message ड৴ console.log('Worker send: ', e.data); }); // messageૹ৴ worker.postMessage('Hello World'); // worker.js self.addEventListener('message',(e) => { // message ड৴ console.log('Main send:', e.data); // message ૹ৴ self.postMessage(e.data); }); γϯϓϧͳ΋ͷͷɺλεΫͷεέδϡʔϦϯά΍ϝϞϦڞ༗ͳ ͲͰ΋ͬͱ8FCͷ࢓૊ΈશମͰΑΓྑ͍"1*΍ํ๏Λ໛ࡧத

Slide 49

Slide 49 text

Make Worker Better Again • WebWorkerͰλεΫฒྻԽ͸Ͱ͖ͯ΋εέ δϡʔϦϯά͕໰୊ʹͳΔɻ • աڈʹ͸JS Schedulerͷproposal΋ɻ

Slide 50

Slide 50 text

Make Worker Better Again • ͦ΋ͦ΋ JavaScript ্Ͱ࣮ࢪ͢ΔͷʹҰ൪͋ͬ ͨϚϧνεϨουϞσϧ͸Կͳͷ͔ʁ • SharedArrayBuffer࢖͏ͷ͕͍͍ͷʁ • WebKitͷํ͸Concurrent JavaScriptͷఏҊ ΋͍ͯͨ͠ɻ

Slide 51

Slide 51 text

Make Worker Better Again • WebKitͷํ͕JSͰฒߦॲཧ͢Δͱ͖ͷํ๏ɺಛʹ SharedArrayBufferΛ࢖ͬͨϞσϧΛৄղ • SharedArrayBuffer࢖͏ͷ͕͍͍ͷʁ • WebKitͷํ͸Concurrent JavaScriptͷఏҊ΋ͯ͠ ͍ͨɻ

Slide 52

Slide 52 text

Make Worker Better Again • Tasklets API • Task ୯ҐͰখ͘͞background taskͱ࣮ͯ͠ ߦͤ͞Δ࢓૊Έ https://nhiroki.jp/2017/12/10/javascript-parallel-processing#6-worklet

Slide 53

Slide 53 text

Make Worker Better Again • StreamͰWorkerܦ༝ͰσʔλՃ޻ • Main͔ΒTransform Workerʹྲྀ͢

Slide 54

Slide 54 text

Make Worker Better Again // Main const worker = new Worker('transcode.js'); worker.onmessage = event => { const transcoder = event.data; await fetch('bunny.vp10') .pipeThrough(transcoder) .pipeTo(videoSink); }; // Worker ଆ importScripts('vp10decode.js', 'mp4encode.js'); const transcoder = new TransformStream({ transform(chunk, controller) { const decoded = vp10decode(chunk); controller.enqueue(mp4encode(decoded)); } }); postMessage(transcoder, [transcoder]);

Slide 55

Slide 55 text

Make Worker Better Again • blöcks • syntax parse, serialize ΛผεϨουͰͰ͖Δ Α͏ʹ͢ΔͨΊͷ৽͍͠ఏҊ // {| … |} ͰผWorker thread Ͱ parse ͤ͞Δ const result = await worker({| const res = await fetch("people.json"); const json = await res.json(); return json[2].firstName; |});

Slide 56

Slide 56 text

Off the main thread·ͱΊ • main threadʹෛՙ͕͔͔Βͳ͍Α͏ʹlighthouseͰϝτϦΫεΛऔΕ ΔΑ͏ʹ͍ͯ͠Δ • Performance ObserverͰLongTaskΛݕ஌͢ΔAPI΋࢓༷ࡦఆத • Worker APIΛ΋ͬͱ࢖͍΍͘͢͢ΔͨΊͷٞ࿦Λ࣮ࢪத • SchedulerͲ͏͢Δ͔ • σʔλڞ༗͸Ͳ͏͢Δ͔ • Tasklets, Transferable Stream, blöcks etc etc

Slide 57

Slide 57 text

·ͱΊ • Web Performance ͷ͜Ε·Ͱ • දࣔͰ͖Δ·Ͱͷߴ଎Խ • ϦΫΤετΛݮΒ͢ɾϨεϙϯεͷόΠταΠζΛݮΒ͢ • ϨΠςϯγΛ࡟Δ (http2) • ෦෼ϨϯμϦϯά (Single Page Apps) • Web Performance ͷ͜Ε͔Β • ૢ࡞Ͱ͖Δ·Ͱɺૢ࡞͔ͯ͠Βͷߴ଎Խ • ͦͷҰ͕ͭWebWorkerΛΑΓྑ͘͢Δํ޲΁ • Worker ʹ͸ເ͕·ͩ٧·ͬͯΔɺࢥ͍͕͋Ε͹ੋඇ࢓༷ࢀՃ΁

Slide 58

Slide 58 text

ࢀߟࢿྉ • ΢Σϒϒϥ΢βͷ off-the-main-thread API ͷ࿩ https://nhiroki.jp/2018/05/07/off-the-main- thread-api • off the main thread with workers https://speakerdeck.com/kosamari/off-the-main-thread-with- workers • improving the developer experience for doing work off the main thread http://bit.ly/blinkon9- omt • web application 2018 from performance perspective https://speakerdeck.com/ yosuke_furukawa/web-application-2018-from-performance-perspective • Speed Focus for 2018 https://docs.google.com/presentation/d/1OBij2sz6gNU- VCrNz7REvJ4piiM21YZnVCUnl6MjUas/edit#slide=id.g372bf772fc_0_55 • high performance web sites https://www.amazon.co.jp/dp/B0028N4WHY/ • high performance browser networking https://www.amazon.co.jp/dp/B00FM0OC4S/