Slide 1

Slide 1 text

Loading Performanceͱͷ
 ޲͖߹͍ํ ೔ຊܦࡁ৽ฉࣾ ٶຊ ক (@shqld)

Slide 2

Slide 2 text

- ٶຊ ক (Sho Miyamoto) - @shqld (Github, Twitter) - ೔ຊܦࡁ৽ฉࣾ ৽ଔ2೥໨ - ࠷ۙ͸։ൃϝΠϯ - r.nikkei.com ͷϑϩϯτɺBFFɺCDN - Իָ - τϥϯϖοτ(JazzFunkܥʣɺϐΞϊ - ౦ೆΞδΞʹॅΈ͍ͨ ͩΕʁ
 Who am I

Slide 3

Slide 3 text

೔ܦిࢠ൛ a.k.a Nikkei 2010೥3݄૑ץ ຖ೔໿900ຊͷهࣄΛ഑৴ ݄ؒ3ԯΞΫηεҎ্ 2017೥11݄ʹϞόΠϧ൛ϦχϡʔΞϧ

Slide 4

Slide 4 text

Google IO 2019 Credit: @sisidovski (twitter) Speed at Scale: Web Performance Tips and Tricks from the Trenches (Google I/O ’19)

Slide 5

Slide 5 text

7݄ʹ2౓໨ͷϦχϡʔΞϧ
 2nd time renewal in next July ະެ։

Slide 6

Slide 6 text

✔ LoadingPerformanceͱ೔ܦిࢠ൛ ✔ ֎෦εΫϦϓτͱύϑΥʔϚϯε ✔ ݎ࿚ੑͱύϑΥʔϚϯε ✔ DXͱύϑΥʔϚϯε ✘ PWA ✘ CDN ✘ αʔόαΠυ ࠓ೔࿩͢͜ͱ Agenda

Slide 7

Slide 7 text

A brief introduction of Loading Performance

Slide 8

Slide 8 text

Loading Performance ϏδωεΠϯύΫτ
 Business Impacts https://dexecure.com/blog/business-web-performance-slow-website-eats-up-your-revenue/

Slide 9

Slide 9 text

Loading Performance ΩʔϝτϦΫε
 Key Metrics https://developers.google.com/web/fundamentals/performance/rail

Slide 10

Slide 10 text

೔ܦిࢠ൛ͷύϑΥʔϚϯε
 Performance on Nikkei

Slide 11

Slide 11 text

LightHouse Score (Top Page) ೔ܦిࢠ൛ͷύϑΥʔϚϯε

Slide 12

Slide 12 text

΋͠ݹ͍୺຤Λ࢖͍ͬͯͨΒʁ ΋͠Windows7 & IEͩͬͨΒʁ ΋͠ΪΨΛ࢖͍Ռ͍ͨͯͨ͠Βʁ ΋͠Wifi͕஗͍؀ڥͩͬͨΒʁ ೔ܦిࢠ൛ͷύϑΥʔϚϯε

Slide 13

Slide 13 text

No Throttling ೔ܦిࢠ൛ͷύϑΥʔϚϯε LightHouse Score (Top Page) Applied Slow 4G, 4x CPU Slowdown

Slide 14

Slide 14 text

- Good FMP - ཉ͍͠ίϯςϯπ͸͙͢ʹݟ͑ΔΑ͏ʹͳΔ - Bad TTI - ϘλϯΛԡͯ͠΋൓Ԡ͕ͳ͍ - ϓϩάϨεόʔ͕ফ͑ͳ͍ ೔ܦిࢠ൛ͷύϑΥʔϚϯε Ͳ͏ͳΔͷ͔ How it affects

Slide 15

Slide 15 text

TTI ೔ܦిࢠ൛ͷύϑΥʔϚϯε ͍ͭͰ΋Ϣʔβ͔ΒͷೖྗΛड͚ΒΕΔঢ়ଶ

Slide 16

Slide 16 text

Bad TTI 5.7s ೔ܦిࢠ൛ͷύϑΥʔϚϯε

Slide 17

Slide 17 text

https://developers.google.com/web/updates/2018/05/first-input-delay جຊతʹ͸First CPU Idleͱಉ͡λΠϛϯά Long Tasks͕Ұఆ࣌ؒͳ͍ঢ়ଶ FIDͱ͸ࣅ͍ͯΔ͕ҟͳΔ ೔ܦిࢠ൛ͷύϑΥʔϚϯε

Slide 18

Slide 18 text

ओͳݪҼ: (֎෦ͷ)޿ࠂεΫϦϓτ Main culprit: external ad scripts ޿ࠂεΫϦϓτ

Slide 19

Slide 19 text

޿ࠂεΫϦϓτ Ad scripts ޿ࠂεΫϦϓτ

Slide 20

Slide 20 text

؆୯ʹಋೖͰ͖Δ
 Introduce easily ࣮֬ʹදࣔ͢Δ
 Display certainly ਖ਼֬ʹܭଌ͢Δ Measure precisely ޿ࠂεΫϦϓτ

Slide 21

Slide 21 text

- ༩͑ΒΕͨεΫϦϓτλάΛష Δ͚ͩͰಋೖͰ͖Δ - ෆมͳεΫϦϓτΛೖΓޱʹ
 ଟஈݺͼग़͠Λ͍ͯ͠Δ ؆୯ʹಋೖͰ͖Δ
 Introduce easily - ωοτϫʔΫϦΫΤετ͕ෳ਺ ճ૸Δ - ίϯτϩʔϧͰ͖ͳ͍ ޿ࠂεΫϦϓτ

Slide 22

Slide 22 text

- ϓϩμΫτͷίʔυʹӨڹ͞Ε ͳ͍Α͏ͳڧ͍࣮૷ - iframeͰදࣔ ࣮֬ʹදࣔ͢Δ
 Display certainly - αΠζ͕͔ͳΓॏ͍ - ࣮ߦ࣌ؒ΋͔ͳΓ௕͍ - `document.write()` ޿ࠂεΫϦϓτ

Slide 23

Slide 23 text

- ޿ࠂ͕Ϣʔβʹݟ͑ͯॳΊͯΠϯ ϓϨογϣϯͷϏʔίϯ͕ඈͿ - ը໘ʹೖΔ·Ͱ޿ࠂΛग़͞ͳ͍ ਖ਼֬ʹܭଌ͢Δ
 Measure precisely - `onScroll` Ͱ؂ࢹ - `img` λάͷsrc ޿ࠂεΫϦϓτ

Slide 24

Slide 24 text

΍ͬͺΓ޿ࠂ͸ͭΒ͍ɺͰ΋֎ͤͳ͍

Slide 25

Slide 25 text

޿ࠂεΫϦϓτͷ࠷దԽ Advertisement Performance τϨʔυΦϑʁ Trade off?

Slide 26

Slide 26 text

޿ࠂεΫϦϓτͷ࠷దԽ Ad Scripts Optimization ޿ࠂεΫϦϓτͷ࠷దԽ

Slide 27

Slide 27 text

ԿΛ͍ͯ͠Δͷ͔෼͔Βͳ͍ υΩϡϝϯτ͕ͳ͍ ͪ͜ΒଆͰ͸มߋͰ͖ͳ͍ ޿ࠂεΫϦϓτͷ࠷దԽ

Slide 28

Slide 28 text

ԿΛ͍ͯ͠Δͷ͔෼͔Βͳ͍ υΩϡϝϯτ͕ͳ͍ ͪ͜ΒଆͰ͸มߋͰ͖ͳ͍ ͦΕͰ΋Ͱ͖Δ͜ͱ͸͋Δ ޿ࠂεΫϦϓτͷ࠷దԽ

Slide 29

Slide 29 text

minify͞ΕͨίʔυΛಡΉ debuggerͰॲཧΛ௥͏ ޿ࠂεΫϦϓτͷ࠷దԽ

Slide 30

Slide 30 text

1. εΫϦϓτΛݺͼग़͢ॲཧΛ୳͢ 2. ଟஈʹݺͼग़͞ΕΔεΫϦϓτΛμ΢ϯϩʔυ 3. ݺͼग़͠෦෼Λ௵͢ 4. 1ϑΝΠϧʹ࿈݁ͯ͠minify 5. Fastly͔Β഑৴ Build ޿ࠂεΫϦϓτͷ࠷దԽ

Slide 31

Slide 31 text

const bundledScripts = [] const script = await fetch(AD_ENTRY_URL) const nextScriptURL = script.match(NEXT_URL_REGEX) bundledScripts.push( script.replace( 'createElement("script")', 'createElement("div")' ) ) const nextScript = fetch(nextScriptURL) // … minify(bundledScripts.join('')) Build ޿ࠂεΫϦϓτͷ࠷దԽ

Slide 32

Slide 32 text

ίϯτϩʔϥɿ޿ࠂSDKΛϥοϓ Ϗϡʔɿ֤ΫϦΤΠςΟϒͷදࣔ෦෼ΛiframeͰϥοϓ Encapsulate ޿ࠂεΫϦϓτͷ࠷దԽ

Slide 33

Slide 33 text

Encapsulate Controller View (iframe) View (iframe) View (iframe) Ad Server ޿ࠂεΫϦϓτͷ࠷దԽ

Slide 34

Slide 34 text

- ίϯτϩʔϥɿSDKͷಈ͖Λ཈੍ - e.g. `onScroll` -> `IntersectionObserver` - Ϗϡʔɿ޿ࠂϨεϙϯεΛड͚औΓऔಘͨ͠
 ΫϦΤΠςΟϒͷHTMLΛύʔε - e.g. `document.write` Override ޿ࠂεΫϦϓτͷ࠷దԽ

Slide 35

Slide 35 text

Off The Main Thread - UIͷදࣔʹؔ͢Δ΋ͷҎ֎͸WebWorkerͰ - ޿ࠂͷϦΫΤετ΍ύʔεΛWorkerͷεϨουͰॲ ཧ͍ͨ͠ - ޿ࠂεΫϦϓτ͕ݺͿϦΫΤετΛ෼ੳͯ͠ɺ WorkerଆͰϦΫΤετΛ૊ΈཱͯΔॲཧΛॻ͘ ޿ࠂεΫϦϓτͷ࠷దԽ

Slide 36

Slide 36 text

import * as Comlink from ‘comlink’ // worker.js const request = () => { const url = new URL('AD_SERVER_ENDPOINT') url.searchParams = { /*...*/ } return fetch(
 url.toString(),
 { headers: { /*...*/ } }
 ).then((res) => res.json()) } Comlink.expose(request) // main.js const request = Comlink.wrap(
 new Worker(paths.controllerWorker) ) // ...
 if (useWorker) { request(sectionId).then(renderAd) } Off The Main Thread ޿ࠂεΫϦϓτͷ࠷దԽ

Slide 37

Slide 37 text

Off The Main Thread ޿ࠂεΫϦϓτͷ࠷దԽ

Slide 38

Slide 38 text

޿ࠂ͸ઈରʹग़͞ͳͯ͘͸ͳΒͳ͍ but… छʑͷ࠷దԽࢪࡦʹΑͬͯ༧ظͤ͵ΫϦΤΠςΟϒͰ දࣔʹࣦഊ͢Δ͜ͱ͕͋Δ

Slide 39

Slide 39 text

Robustness Performance τϨʔυΦϑʁ Trade off? ୤࠷దԽ

Slide 40

Slide 40 text

୤࠷దԽ
 Deoptimization ୤࠷దԽ

Slide 41

Slide 41 text

Ͳ͔͜ͰҰ౓Ͱ΋ॲཧʹࣦഊͨ͠ͱ͖
 ͔ͦ͜Βਖ਼نͷॲཧʹ੾Γସ࣮͑ͯߦ if (!expectedData) { deoptimize() } try { process() } catch { deoptimize() } ୤࠷దԽ ࣦഊ࣌ͷϑΥʔϧόοΫ
 Fallback on failure

Slide 42

Slide 42 text

Optimized
 Ad Handler Ad Ad Ad Deoptimize Default
 Ad Handler ࣦഊ࣌ͷϑΥʔϧόοΫ
 Fallback on failure ୤࠷దԽ

Slide 43

Slide 43 text

2nd-level ୤࠷దԽ Dynamic Deoptimization optimized 3rd-level default

Slide 44

Slide 44 text

- ෳ਺ͷ࠷దԽϨϕϧΛઃఆ - σϑΥϧτ͸࠷΋ߴ͍Ϩϕϧ - ϙΠϯτͱͳΔՕॴͰͷॲཧʹࣦഊͨ͠ΒɺҰͭϨ ϕϧΛԼ͛ͯܧଓ - ABςετͰσϑΥϧτϨϕϧΛ෼͚Ε͹
 ֤Ϩϕϧͷ࠷దԽॲཧͷΠϯύΫτ΍੒ޭ཰ΛଌΕ Δɺͱ͍͏෭࣍తͳϝϦοτ΋ ୤࠷దԽ Dynamic Deoptimization

Slide 45

Slide 45 text

ύϑΥʔϚϯεΛ௥͍ٻΊΔͱɺ
 ։ൃମݧ͕௿͘ͳΔέʔε΋͋Δ

Slide 46

Slide 46 text

ϑϩϯτΤϯυઃܭͷ࡮৽ Developer
 Experience Performance τϨʔυΦϑʁ Trade off?

Slide 47

Slide 47 text

- จࣈྻςϯϓϨʔτ & VanillaJS͸ͭΒ͍ - όά΋ग़΍͍͢ - ։ൃऀͷࢀೖোนʹͳΔ ϞμϯͳϑϨʔϜϫʔΫͰ҆৺ɾշదʹ։ൃ͍ͨ͠ ϑϩϯτΤϯυઃܭͷ࡮৽ ύϑΥʔϚϯεͷཪͰ Behind the scenes

Slide 48

Slide 48 text

ϑϩϯτΤϯυઃܭͷ࡮৽ Redesigning Frontend ϑϩϯτΤϯυઃܭͷ࡮৽

Slide 49

Slide 49 text

Frontend Backend VanillaJS ϑϩϯτΤϯυઃܭͷ࡮৽ Handlebars ~ 2018

Slide 50

Slide 50 text

ϑϩϯτΤϯυઃܭͷ࡮৽ Frontend Backend JSX VanillaJS Handlebars ~ 2018 2019 ~

Slide 51

Slide 51 text

ϑϩϯτΤϯυઃܭͷ࡮৽ Backend Frontend JSX VanillaJS VanillaJS Handlebars ~ 2018 2019 ~

Slide 52

Slide 52 text

- جຊతʹCSR͸͠ͳͯ͘Α͍ - Universalͳίϯϙʔωϯτ࣮૷͸ඞཁͳ͍ - ͱ͸͍͑ΠϯλϥΫγϣϯཁૉ͸গͳ͘ͳ͍ - ը૾ͷLazyloadɺ ೔࣌ͷ૬ରදࣔɺ֤छϘλϯ… ϑϩϯτΤϯυઃܭͷ࡮৽ ੩తͳαΠτ͸ Static websites is …

Slide 53

Slide 53 text

ϑϩϯτΤϯυઃܭͷ࡮৽ ඞཁͷͳ͍΋ͷ Dispensable stuff Components State React

Slide 54

Slide 54 text

VNode VNode VNode VNode Building
 Virtual DOM Tree ϑϩϯτΤϯυઃܭͷ࡮৽ Hydration ඞཁͷͳ͍΋ͷ Dispensable stuff

Slide 55

Slide 55 text

ϑϩϯτΤϯυઃܭͷ࡮৽ WebComponents/ CustomElements ✔ ϥΠϒϥϦෆཁ
 ✔ ωΠςΟϒ࣮૷ ✔ Webඪ४ ✔ ੜDOMૢ࡞ͱൺ΂ͯ͸Δ͔ʹָ ✔ SSRͷ࣮૷ͱᴥᴪ͕ͳ͍

Slide 56

Slide 56 text

ϑϩϯτΤϯυઃܭͷ࡮৽ WebComponents/ CustomElements export const Card = (props) => (

{props.title}


 {props.publishedAt}
 
 {props.thumbnail}

)

Slide 57

Slide 57 text

·ͱΊ
 Summary

Slide 58

Slide 58 text

ۜͷ஄ؙ͸ଘࡏ͠ͳ͍ τϨʔυΦϑ͕͋ͬͯ΋ఘΊͳ͍ Կ͕ඞཁͳͷ͔ ԿΛ͢΂͖ͳͷ͔ Ͱ͖Δ͜ͱΛண࣮ʹ΍͍ͬͯ͘ ·ͱΊ

Slide 59

Slide 59 text

͋Γ͕ͱ͏͍͟͝·ͨ͠ Thank you