Upgrade to Pro — share decks privately, control downloads, hide ads and more …

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

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

Sho Miyamoto

May 18, 2019
Tweet

More Decks by Sho Miyamoto

Other Decks in Technology

Transcript

  1. Loading Performanceͱͷ

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

    View Slide

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

    Who am I

    View Slide

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

    View Slide

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

    View Slide

  5. 7݄ʹ2౓໨ͷϦχϡʔΞϧ

    2nd time renewal in next July
    ະެ։

    View Slide

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

    View Slide

  7. A brief introduction of
    Loading Performance

    View Slide

  8. Loading Performance
    ϏδωεΠϯύΫτ

    Business Impacts
    https://dexecure.com/blog/business-web-performance-slow-website-eats-up-your-revenue/

    View Slide

  9. Loading Performance
    ΩʔϝτϦΫε

    Key Metrics
    https://developers.google.com/web/fundamentals/performance/rail

    View Slide

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

    Performance on Nikkei

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  20. ؆୯ʹಋೖͰ͖Δ

    Introduce easily
    ࣮֬ʹදࣔ͢Δ

    Display certainly
    ਖ਼֬ʹܭଌ͢Δ
    Measure precisely
    ޿ࠂεΫϦϓτ

    View Slide

  21. - ༩͑ΒΕͨεΫϦϓτλάΛష
    Δ͚ͩͰಋೖͰ͖Δ
    - ෆมͳεΫϦϓτΛೖΓޱʹ

    ଟஈݺͼग़͠Λ͍ͯ͠Δ
    ؆୯ʹಋೖͰ͖Δ

    Introduce easily
    - ωοτϫʔΫϦΫΤετ͕ෳ਺
    ճ૸Δ
    - ίϯτϩʔϧͰ͖ͳ͍
    ޿ࠂεΫϦϓτ

    View Slide

  22. - ϓϩμΫτͷίʔυʹӨڹ͞Ε
    ͳ͍Α͏ͳڧ͍࣮૷
    - iframeͰදࣔ
    ࣮֬ʹදࣔ͢Δ

    Display certainly
    - αΠζ͕͔ͳΓॏ͍
    - ࣮ߦ࣌ؒ΋͔ͳΓ௕͍
    - `document.write()`
    ޿ࠂεΫϦϓτ

    View Slide

  23. - ޿ࠂ͕Ϣʔβʹݟ͑ͯॳΊͯΠϯ
    ϓϨογϣϯͷϏʔίϯ͕ඈͿ
    - ը໘ʹೖΔ·Ͱ޿ࠂΛग़͞ͳ͍
    ਖ਼֬ʹܭଌ͢Δ

    Measure precisely
    - `onScroll` Ͱ؂ࢹ
    - `img` λάͷsrc
    ޿ࠂεΫϦϓτ

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  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
    ޿ࠂεΫϦϓτͷ࠷దԽ

    View Slide

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

    View Slide

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

    View Slide

  34. - ίϯτϩʔϥɿSDKͷಈ͖Λ཈੍
    - e.g. `onScroll` -> `IntersectionObserver`
    - Ϗϡʔɿ޿ࠂϨεϙϯεΛड͚औΓऔಘͨ͠

    ΫϦΤΠςΟϒͷHTMLΛύʔε
    - e.g. `document.write`
    Override
    ޿ࠂεΫϦϓτͷ࠷దԽ

    View Slide

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

    View Slide

  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
    ޿ࠂεΫϦϓτͷ࠷దԽ

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  40. ୤࠷దԽ

    Deoptimization
    ୤࠷దԽ

    View Slide

  41. Ͳ͔͜ͰҰ౓Ͱ΋ॲཧʹࣦഊͨ͠ͱ͖

    ͔ͦ͜Βਖ਼نͷॲཧʹ੾Γସ࣮͑ͯߦ
    if (!expectedData) { deoptimize() }
    try { process() } catch { deoptimize() }
    ୤࠷దԽ
    ࣦഊ࣌ͷϑΥʔϧόοΫ

    Fallback on failure

    View Slide

  42. Optimized

    Ad Handler
    Ad
    Ad
    Ad
    Deoptimize
    Default

    Ad Handler
    ࣦഊ࣌ͷϑΥʔϧόοΫ

    Fallback on failure
    ୤࠷దԽ

    View Slide

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

    View Slide

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

    ֤Ϩϕϧͷ࠷దԽॲཧͷΠϯύΫτ΍੒ޭ཰ΛଌΕ
    Δɺͱ͍͏෭࣍తͳϝϦοτ΋
    ୤࠷దԽ
    Dynamic
    Deoptimization

    View Slide

  45. ύϑΥʔϚϯεΛ௥͍ٻΊΔͱɺ

    ։ൃମݧ͕௿͘ͳΔέʔε΋͋Δ

    View Slide

  46. ϑϩϯτΤϯυઃܭͷ࡮৽
    Developer

    Experience
    Performance
    τϨʔυΦϑʁ
    Trade off?

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  54. VNode
    VNode VNode
    VNode
    Building

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

    View Slide

  55. ϑϩϯτΤϯυઃܭͷ࡮৽
    WebComponents/
    CustomElements
    ✔ ϥΠϒϥϦෆཁ

    ✔ ωΠςΟϒ࣮૷
    ✔ Webඪ४
    ✔ ੜDOMૢ࡞ͱൺ΂ͯ͸Δ͔ʹָ
    ✔ SSRͷ࣮૷ͱᴥᴪ͕ͳ͍

    View Slide

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

    {props.title}

    {props.publishedAt}



    {props.thumbnail}



    )

    View Slide

  57. ·ͱΊ

    Summary

    View Slide

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

    View Slide

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

    View Slide