Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Loading Performanceとの向き合い方 / InsideFrontend 2019
Search
Sho Miyamoto
May 18, 2019
Technology
2.4k
8
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Loading Performanceとの向き合い方 / InsideFrontend 2019
Sho Miyamoto
May 18, 2019
More Decks by Sho Miyamoto
See All by Sho Miyamoto
JavaScriptエンジンから見るランタイム / 2024-04-25
shqld
12
2.3k
Proxy-Status & Cache-Status
shqld
0
660
High Performance JavaScript / jsconfjp2019
shqld
0
640
FastlyとTypeScriptで実現するカナリアリリース / yamagoya2020
shqld
21
7.5k
ServiceWorkerの開発 / ServiceWorker Development
shqld
3
800
日経電子版とPWAのこれから / PWANight vol.2
shqld
2
5.1k
日経電子版のマイクロフロントエンドとPWA / devsum2019
shqld
8
13k
Other Decks in Technology
See All in Technology
データベース研修【MIXI 26新卒技術研修】
mixi_engineers
PRO
1
630
人依存からAIネイティブの体制へ:バックエンド開発の裏側【SORACOM Discovery 2026】
soracom
PRO
0
120
それでも、技術なブログを書く理由 #kichijojipm / Why I Still Write Tech Blogs Even Now
shinkufencer
0
1.2k
新たなDBアーキテクチャ「LTAP」にDeep Dive!!
inoutk
0
140
CTOキーノート:AI時代の「つなぐ」を再定義 ― 真のIoTとリアルワールドAI【SORACOM Discovery 2026】
soracom
PRO
0
310
DevOps Agentで運用判断をチーム資産にする~Agent InstructionsとAgent Skillを継続的に育てる~
fujioka6789
0
170
論語・武士道・産業革命から見る かわるもの、かわらないもの
ichimichi
8
1.5k
現場との対話から始める “作る前に問い直す”業務改善
mochico50
2
330
基調講演:人とAIをつなぐIoTの今と未来 ー 「フィジカル」と「デジタル」が出会うその先へ【SORACOM Discovery 2026】
soracom
PRO
0
350
A Bag-of-Documents Model for Query Specificity
dtunkelang
0
150
インシデント事例と パッケージの全量解析に学ぶ ソフトウェアサプライチェーンの守り方 / supply-chain-attack-defense
flatt_security
0
1.2k
NetBoxを利用した作業効率化の試み_NetDevNight4
tnoha
0
190
Featured
See All Featured
How to Build an AI Search Optimization Roadmap - Criteria and Steps to Take #SEOIRL
aleyda
1
2.1k
Ecommerce SEO: The Keys for Success Now & Beyond - #SERPConf2024
aleyda
1
2.1k
Marketing Yourself as an Engineer | Alaka | Gurzu
gurzu
0
260
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
360
30k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
231
55k
Un-Boring Meetings
codingconduct
0
350
Design of three-dimensional binary manipulators for pick-and-place task avoiding obstacles (IECON2024)
konakalab
0
500
Navigating Team Friction
lara
192
16k
Six Lessons from altMBA
skipperchong
29
4.4k
How People are Using Generative and Agentic AI to Supercharge Their Products, Projects, Services and Value Streams Today
helenjbeal
1
250
Collaborative Software Design: How to facilitate domain modelling decisions
baasie
1
270
Ten Tips & Tricks for a 🌱 transition
stuffmc
0
160
Transcript
Loading Performanceͱͷ ͖߹͍ํ ຊܦࡁ৽ฉࣾ ٶຊ ক (@shqld)
- ٶຊ ক (Sho Miyamoto) - @shqld (Github, Twitter) -
ຊܦࡁ৽ฉࣾ ৽ଔ2 - ࠷ۙ։ൃϝΠϯ - r.nikkei.com ͷϑϩϯτɺBFFɺCDN - Իָ - τϥϯϖοτ(JazzFunkܥʣɺϐΞϊ - ౦ೆΞδΞʹॅΈ͍ͨ ͩΕʁ Who am I
ܦిࢠ൛ a.k.a Nikkei 20103݄ץ ຖ900ຊͷهࣄΛ৴ ݄ؒ3ԯΞΫηεҎ্ 201711݄ʹϞόΠϧ൛ϦχϡʔΞϧ
Google IO 2019 Credit: @sisidovski (twitter) Speed at Scale: Web
Performance Tips and Tricks from the Trenches (Google I/O ’19)
7݄ʹ2ͷϦχϡʔΞϧ 2nd time renewal in next July ະެ։
✔ LoadingPerformanceͱܦిࢠ൛ ✔ ֎෦εΫϦϓτͱύϑΥʔϚϯε ✔ ݎ࿚ੑͱύϑΥʔϚϯε ✔ DXͱύϑΥʔϚϯε ✘ PWA
✘ CDN ✘ αʔόαΠυ ࠓ͢͜ͱ Agenda
A brief introduction of Loading Performance
Loading Performance ϏδωεΠϯύΫτ Business Impacts https://dexecure.com/blog/business-web-performance-slow-website-eats-up-your-revenue/
Loading Performance ΩʔϝτϦΫε Key Metrics https://developers.google.com/web/fundamentals/performance/rail
ܦిࢠ൛ͷύϑΥʔϚϯε Performance on Nikkei
LightHouse Score (Top Page) ܦిࢠ൛ͷύϑΥʔϚϯε
͠ݹ͍Λ͍ͬͯͨΒʁ ͠Windows7 & IEͩͬͨΒʁ ͠ΪΨΛ͍Ռ͍ͨͯͨ͠Βʁ ͠Wifi͕͍ڥͩͬͨΒʁ ܦిࢠ൛ͷύϑΥʔϚϯε
No Throttling ܦిࢠ൛ͷύϑΥʔϚϯε LightHouse Score (Top Page) Applied Slow 4G,
4x CPU Slowdown
- Good FMP - ཉ͍͠ίϯςϯπ͙͢ʹݟ͑ΔΑ͏ʹͳΔ - Bad TTI - ϘλϯΛԡͯ͠Ԡ͕ͳ͍
- ϓϩάϨεόʔ͕ফ͑ͳ͍ ܦిࢠ൛ͷύϑΥʔϚϯε Ͳ͏ͳΔͷ͔ How it affects
TTI ܦిࢠ൛ͷύϑΥʔϚϯε ͍ͭͰϢʔβ͔ΒͷೖྗΛड͚ΒΕΔঢ়ଶ
Bad TTI 5.7s ܦిࢠ൛ͷύϑΥʔϚϯε
https://developers.google.com/web/updates/2018/05/first-input-delay جຊతʹFirst CPU Idleͱಉ͡λΠϛϯά Long Tasks͕Ұఆ࣌ؒͳ͍ঢ়ଶ FIDͱࣅ͍ͯΔ͕ҟͳΔ ܦిࢠ൛ͷύϑΥʔϚϯε
ओͳݪҼ: (֎෦ͷ)ࠂεΫϦϓτ Main culprit: external ad scripts ࠂεΫϦϓτ
ࠂεΫϦϓτ Ad scripts ࠂεΫϦϓτ
؆୯ʹಋೖͰ͖Δ Introduce easily ࣮֬ʹදࣔ͢Δ Display certainly ਖ਼֬ʹܭଌ͢Δ Measure precisely ࠂεΫϦϓτ
- ༩͑ΒΕͨεΫϦϓτλάΛష Δ͚ͩͰಋೖͰ͖Δ - ෆมͳεΫϦϓτΛೖΓޱʹ ଟஈݺͼग़͠Λ͍ͯ͠Δ ؆୯ʹಋೖͰ͖Δ Introduce easily -
ωοτϫʔΫϦΫΤετ͕ෳ ճΔ - ίϯτϩʔϧͰ͖ͳ͍ ࠂεΫϦϓτ
- ϓϩμΫτͷίʔυʹӨڹ͞Ε ͳ͍Α͏ͳڧ͍࣮ - iframeͰදࣔ ࣮֬ʹදࣔ͢Δ Display certainly - αΠζ͕͔ͳΓॏ͍
- ࣮ߦ͔࣌ؒͳΓ͍ - `document.write()` ࠂεΫϦϓτ
- ࠂ͕Ϣʔβʹݟ͑ͯॳΊͯΠϯ ϓϨογϣϯͷϏʔίϯ͕ඈͿ - ը໘ʹೖΔ·ͰࠂΛग़͞ͳ͍ ਖ਼֬ʹܭଌ͢Δ Measure precisely - `onScroll`
Ͱࢹ - `img` λάͷsrc ࠂεΫϦϓτ
ͬͺΓࠂͭΒ͍ɺͰ֎ͤͳ͍
ࠂεΫϦϓτͷ࠷దԽ Advertisement Performance τϨʔυΦϑʁ Trade off?
ࠂεΫϦϓτͷ࠷దԽ Ad Scripts Optimization ࠂεΫϦϓτͷ࠷దԽ
ԿΛ͍ͯ͠Δͷ͔͔Βͳ͍ υΩϡϝϯτ͕ͳ͍ ͪ͜ΒଆͰมߋͰ͖ͳ͍ ࠂεΫϦϓτͷ࠷దԽ
ԿΛ͍ͯ͠Δͷ͔͔Βͳ͍ υΩϡϝϯτ͕ͳ͍ ͪ͜ΒଆͰมߋͰ͖ͳ͍ ͦΕͰͰ͖Δ͜ͱ͋Δ ࠂεΫϦϓτͷ࠷దԽ
minify͞ΕͨίʔυΛಡΉ debuggerͰॲཧΛ͏ ࠂεΫϦϓτͷ࠷దԽ
1. εΫϦϓτΛݺͼग़͢ॲཧΛ୳͢ 2. ଟஈʹݺͼग़͞ΕΔεΫϦϓτΛμϯϩʔυ 3. ݺͼग़͠෦Λ௵͢ 4. 1ϑΝΠϧʹ࿈݁ͯ͠minify 5. Fastly͔Β৴
Build ࠂεΫϦϓτͷ࠷దԽ
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 ࠂεΫϦϓτͷ࠷దԽ
ίϯτϩʔϥɿࠂSDKΛϥοϓ Ϗϡʔɿ֤ΫϦΤΠςΟϒͷදࣔ෦ΛiframeͰϥοϓ Encapsulate ࠂεΫϦϓτͷ࠷దԽ
Encapsulate Controller View (iframe) View (iframe) View (iframe) Ad Server
ࠂεΫϦϓτͷ࠷దԽ
- ίϯτϩʔϥɿSDKͷಈ͖Λ੍ - e.g. `onScroll` -> `IntersectionObserver` - ϏϡʔɿࠂϨεϙϯεΛड͚औΓऔಘͨ͠ ΫϦΤΠςΟϒͷHTMLΛύʔε
- e.g. `document.write` Override ࠂεΫϦϓτͷ࠷దԽ
Off The Main Thread - UIͷදࣔʹؔ͢ΔͷҎ֎WebWorkerͰ - ࠂͷϦΫΤετύʔεΛWorkerͷεϨουͰॲ ཧ͍ͨ͠ -
ࠂεΫϦϓτ͕ݺͿϦΫΤετΛੳͯ͠ɺ WorkerଆͰϦΫΤετΛΈཱͯΔॲཧΛॻ͘ ࠂεΫϦϓτͷ࠷దԽ
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 ࠂεΫϦϓτͷ࠷దԽ
Off The Main Thread ࠂεΫϦϓτͷ࠷దԽ
ࠂઈରʹग़͞ͳͯ͘ͳΒͳ͍ but… छʑͷ࠷దԽࢪࡦʹΑͬͯ༧ظͤ͵ΫϦΤΠςΟϒͰ දࣔʹࣦഊ͢Δ͜ͱ͕͋Δ
Robustness Performance τϨʔυΦϑʁ Trade off? ࠷దԽ
࠷దԽ Deoptimization ࠷దԽ
Ͳ͔͜ͰҰͰॲཧʹࣦഊͨ͠ͱ͖ ͔ͦ͜Βਖ਼نͷॲཧʹΓସ࣮͑ͯߦ if (!expectedData) { deoptimize() } try { process()
} catch { deoptimize() } ࠷దԽ ࣦഊ࣌ͷϑΥʔϧόοΫ Fallback on failure
Optimized Ad Handler Ad Ad Ad Deoptimize Default Ad Handler
ࣦഊ࣌ͷϑΥʔϧόοΫ Fallback on failure ࠷దԽ
2nd-level ࠷దԽ Dynamic Deoptimization optimized 3rd-level default
- ෳͷ࠷దԽϨϕϧΛઃఆ - σϑΥϧτ࠷ߴ͍Ϩϕϧ - ϙΠϯτͱͳΔՕॴͰͷॲཧʹࣦഊͨ͠ΒɺҰͭϨ ϕϧΛԼ͛ͯܧଓ - ABςετͰσϑΥϧτϨϕϧΛ͚Ε ֤Ϩϕϧͷ࠷దԽॲཧͷΠϯύΫτޭΛଌΕ
Δɺͱ͍͏෭࣍తͳϝϦοτ ࠷దԽ Dynamic Deoptimization
ύϑΥʔϚϯεΛ͍ٻΊΔͱɺ ։ൃମݧ͕͘ͳΔέʔε͋Δ
ϑϩϯτΤϯυઃܭͷ৽ Developer Experience Performance τϨʔυΦϑʁ Trade off?
- จࣈྻςϯϓϨʔτ & VanillaJSͭΒ͍ - όάग़͍͢ - ։ൃऀͷࢀೖোนʹͳΔ ϞμϯͳϑϨʔϜϫʔΫͰ҆৺ɾշదʹ։ൃ͍ͨ͠ ϑϩϯτΤϯυઃܭͷ৽
ύϑΥʔϚϯεͷཪͰ Behind the scenes
ϑϩϯτΤϯυઃܭͷ৽ Redesigning Frontend ϑϩϯτΤϯυઃܭͷ৽
Frontend Backend VanillaJS ϑϩϯτΤϯυઃܭͷ৽ Handlebars ~ 2018
ϑϩϯτΤϯυઃܭͷ৽ Frontend Backend JSX VanillaJS Handlebars ~ 2018 2019 ~
ϑϩϯτΤϯυઃܭͷ৽ Backend Frontend JSX VanillaJS VanillaJS Handlebars ~ 2018 2019
~
- جຊతʹCSR͠ͳͯ͘Α͍ - Universalͳίϯϙʔωϯτ࣮ඞཁͳ͍ - ͱ͍͑ΠϯλϥΫγϣϯཁૉগͳ͘ͳ͍ - ը૾ͷLazyloadɺ ࣌ͷ૬ରදࣔɺ֤छϘλϯ… ϑϩϯτΤϯυઃܭͷ৽
੩తͳαΠτ Static websites is …
ϑϩϯτΤϯυઃܭͷ৽ ඞཁͷͳ͍ͷ Dispensable stuff Components State React
VNode VNode VNode VNode Building Virtual DOM Tree ϑϩϯτΤϯυઃܭͷ৽ Hydration
ඞཁͷͳ͍ͷ Dispensable stuff
ϑϩϯτΤϯυઃܭͷ৽ WebComponents/ CustomElements ✔ ϥΠϒϥϦෆཁ ✔ ωΠςΟϒ࣮ ✔ Webඪ४ ✔
ੜDOMૢ࡞ͱൺͯΔ͔ʹָ ✔ SSRͷ࣮ͱᴥᴪ͕ͳ͍
ϑϩϯτΤϯυઃܭͷ৽ 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> )
·ͱΊ Summary
ۜͷؙଘࡏ͠ͳ͍ τϨʔυΦϑ͕͋ͬͯఘΊͳ͍ Կ͕ඞཁͳͷ͔ ԿΛ͖͢ͳͷ͔ Ͱ͖Δ͜ͱΛண࣮ʹ͍ͬͯ͘ ·ͱΊ
͋Γ͕ͱ͏͍͟͝·ͨ͠ Thank you