Loading Performanceとの向き合い方 / InsideFrontend 2019

Loading Performanceとの向き合い方 / InsideFrontend 2019

96030bc60c6fc8a91f25ccda9b413b24?s=128

Sho Miyamoto

May 18, 2019
Tweet

Transcript

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

  2. - ٶຊ ক (Sho Miyamoto) - @shqld (Github, Twitter) -

    ೔ຊܦࡁ৽ฉࣾ ৽ଔ2೥໨ - ࠷ۙ͸։ൃϝΠϯ - r.nikkei.com ͷϑϩϯτɺBFFɺCDN - Իָ - τϥϯϖοτ(JazzFunkܥʣɺϐΞϊ - ౦ೆΞδΞʹॅΈ͍ͨ ͩΕʁ
 Who am I
  3. ೔ܦిࢠ൛ a.k.a Nikkei 2010೥3݄૑ץ ຖ೔໿900ຊͷهࣄΛ഑৴ ݄ؒ3ԯΞΫηεҎ্ 2017೥11݄ʹϞόΠϧ൛ϦχϡʔΞϧ

  4. Google IO 2019 Credit: @sisidovski (twitter) Speed at Scale: Web

    Performance Tips and Tricks from the Trenches (Google I/O ’19)
  5. 7݄ʹ2౓໨ͷϦχϡʔΞϧ
 2nd time renewal in next July ະެ։

  6. ✔ LoadingPerformanceͱ೔ܦిࢠ൛ ✔ ֎෦εΫϦϓτͱύϑΥʔϚϯε ✔ ݎ࿚ੑͱύϑΥʔϚϯε ✔ DXͱύϑΥʔϚϯε ✘ PWA

    ✘ CDN ✘ αʔόαΠυ ࠓ೔࿩͢͜ͱ Agenda
  7. A brief introduction of Loading Performance

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

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

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

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

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

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

    4x CPU Slowdown
  14. - Good FMP - ཉ͍͠ίϯςϯπ͸͙͢ʹݟ͑ΔΑ͏ʹͳΔ - Bad TTI - ϘλϯΛԡͯ͠΋൓Ԡ͕ͳ͍

    - ϓϩάϨεόʔ͕ফ͑ͳ͍ ೔ܦిࢠ൛ͷύϑΥʔϚϯε Ͳ͏ͳΔͷ͔ How it affects
  15. TTI ೔ܦిࢠ൛ͷύϑΥʔϚϯε ͍ͭͰ΋Ϣʔβ͔ΒͷೖྗΛड͚ΒΕΔঢ়ଶ

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

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

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

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

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

  21. - ༩͑ΒΕͨεΫϦϓτλάΛష Δ͚ͩͰಋೖͰ͖Δ - ෆมͳεΫϦϓτΛೖΓޱʹ
 ଟஈݺͼग़͠Λ͍ͯ͠Δ ؆୯ʹಋೖͰ͖Δ
 Introduce easily -

    ωοτϫʔΫϦΫΤετ͕ෳ਺ ճ૸Δ - ίϯτϩʔϧͰ͖ͳ͍ ޿ࠂεΫϦϓτ
  22. - ϓϩμΫτͷίʔυʹӨڹ͞Ε ͳ͍Α͏ͳڧ͍࣮૷ - iframeͰදࣔ ࣮֬ʹදࣔ͢Δ
 Display certainly - αΠζ͕͔ͳΓॏ͍

    - ࣮ߦ࣌ؒ΋͔ͳΓ௕͍ - `document.write()` ޿ࠂεΫϦϓτ
  23. - ޿ࠂ͕Ϣʔβʹݟ͑ͯॳΊͯΠϯ ϓϨογϣϯͷϏʔίϯ͕ඈͿ - ը໘ʹೖΔ·Ͱ޿ࠂΛग़͞ͳ͍ ਖ਼֬ʹܭଌ͢Δ
 Measure precisely - `onScroll`

    Ͱ؂ࢹ - `img` λάͷsrc ޿ࠂεΫϦϓτ
  24. ΍ͬͺΓ޿ࠂ͸ͭΒ͍ɺͰ΋֎ͤͳ͍

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

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

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

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

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

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

    Build ޿ࠂεΫϦϓτͷ࠷దԽ
  31. 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 ޿ࠂεΫϦϓτͷ࠷దԽ
  32. ίϯτϩʔϥɿ޿ࠂSDKΛϥοϓ Ϗϡʔɿ֤ΫϦΤΠςΟϒͷදࣔ෦෼ΛiframeͰϥοϓ Encapsulate ޿ࠂεΫϦϓτͷ࠷దԽ

  33. Encapsulate Controller View (iframe) View (iframe) View (iframe) Ad Server

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

    - e.g. `document.write` Override ޿ࠂεΫϦϓτͷ࠷దԽ
  35. Off The Main Thread - UIͷදࣔʹؔ͢Δ΋ͷҎ֎͸WebWorkerͰ - ޿ࠂͷϦΫΤετ΍ύʔεΛWorkerͷεϨουͰॲ ཧ͍ͨ͠ -

    ޿ࠂεΫϦϓτ͕ݺͿϦΫΤετΛ෼ੳͯ͠ɺ WorkerଆͰϦΫΤετΛ૊ΈཱͯΔॲཧΛॻ͘ ޿ࠂεΫϦϓτͷ࠷దԽ
  36. 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 ޿ࠂεΫϦϓτͷ࠷దԽ
  37. Off The Main Thread ޿ࠂεΫϦϓτͷ࠷దԽ

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

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

  40. ୤࠷దԽ
 Deoptimization ୤࠷దԽ

  41. Ͳ͔͜ͰҰ౓Ͱ΋ॲཧʹࣦഊͨ͠ͱ͖
 ͔ͦ͜Βਖ਼نͷॲཧʹ੾Γସ࣮͑ͯߦ if (!expectedData) { deoptimize() } try { process()

    } catch { deoptimize() } ୤࠷దԽ ࣦഊ࣌ͷϑΥʔϧόοΫ
 Fallback on failure
  42. Optimized
 Ad Handler Ad Ad Ad Deoptimize Default
 Ad Handler

    ࣦഊ࣌ͷϑΥʔϧόοΫ
 Fallback on failure ୤࠷దԽ
  43. 2nd-level ୤࠷దԽ Dynamic Deoptimization optimized 3rd-level default

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

    Δɺͱ͍͏෭࣍తͳϝϦοτ΋ ୤࠷దԽ Dynamic Deoptimization
  45. ύϑΥʔϚϯεΛ௥͍ٻΊΔͱɺ
 ։ൃମݧ͕௿͘ͳΔέʔε΋͋Δ

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

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

    ύϑΥʔϚϯεͷཪͰ Behind the scenes
  48. ϑϩϯτΤϯυઃܭͷ࡮৽ Redesigning Frontend ϑϩϯτΤϯυઃܭͷ࡮৽

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

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

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

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

    ੩తͳαΠτ͸ Static websites is …
  53. ϑϩϯτΤϯυઃܭͷ࡮৽ ඞཁͷͳ͍΋ͷ Dispensable stuff Components State React

  54. VNode VNode VNode VNode Building
 Virtual DOM Tree ϑϩϯτΤϯυઃܭͷ࡮৽ Hydration

    ඞཁͷͳ͍΋ͷ Dispensable stuff
  55. ϑϩϯτΤϯυઃܭͷ࡮৽ WebComponents/ CustomElements ✔ ϥΠϒϥϦෆཁ
 ✔ ωΠςΟϒ࣮૷ ✔ Webඪ४ ✔

    ੜDOMૢ࡞ͱൺ΂ͯ͸Δ͔ʹָ ✔ SSRͷ࣮૷ͱᴥᴪ͕ͳ͍
  56. ϑϩϯτΤϯυઃܭͷ࡮৽ WebComponents/ CustomElements export const Card = (props) => (

    <div class=“card"> <p>{props.title}</p> <nikkei-time>
 {props.publishedAt}
 </nikkei-time> <nikkei-picture>
 {props.thumbnail}
 </nikkei-picture> </div> )
  57. ·ͱΊ
 Summary

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

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