Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
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
690
High Performance JavaScript / jsconfjp2019
shqld
0
650
FastlyとTypeScriptで実現するカナリアリリース / yamagoya2020
shqld
21
7.6k
ServiceWorkerの開発 / ServiceWorker Development
shqld
3
800
日経電子版とPWAのこれから / PWANight vol.2
shqld
2
5.2k
日経電子版のマイクロフロントエンドとPWA / devsum2019
shqld
8
13k
Other Decks in Technology
See All in Technology
[JAWS Festa 2026]一番いい仕事は、請求書に現れない / jawsfesta2026
sh_fk2
2
430
eBPF 簡介 2026 版
shunghsiyu
0
190
プロダクションコードにおける encoding/json から encoding/json/v2 へのスムーズな移行
sansantech
PRO
1
240
81天的 AI Agent 軟體開發團隊治理實務分享
regionbbs
0
150
Claude Codeで作ったアプリを安全に公開する/Built with Claude Japan 2026
yoshidashingo
0
220
ゼロから作るWebアプリの新定番!?Amplify Gen 2 × AWS Blocksで実現する「開発速度とRDBの柔軟性のいいとこ取り」
amixedcolor
1
200
Sizing, Benchmarking and Performance Tuning Apache Flink Clusters
rmetzger
0
150
An Introduction to Context Ontology Accelerator (teaching AI agents what your data means)
inariku
PRO
1
200
並列度を下げたら速くなった — go build の重複コンパイルを実測で見る
tomoaki25
2
1k
Copilot Coworkで「みのるん式」やってみた
minorun365
PRO
2
1.7k
Context Ontology Accelerator 入門 (業務データの意味を、AI エージェントに渡す)
inariku
PRO
3
620
サボる子はいねぇがー!AgentCoreハーネスの脆弱性に学ぶ、エージェントの入力バリデーション
iwamot
PRO
5
320
Featured
See All Featured
Typedesign – Prime Four
hannesfritz
42
3.2k
A better future with KSS
kneath
240
18k
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
46
3.1k
Heart Work Chapter 1 - Part 1
lfama
PRO
10
37k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
47
8.4k
StorybookのUI Testing Handbookを読んだ
zakiyama
31
7k
The B2B funnel & how to create a winning content strategy
katarinadahlin
PRO
1
610
Public Speaking Without Barfing On Your Shoes - THAT 2023
reverentgeek
1
660
Docker and Python
trallard
47
4.3k
From Legacy to Launchpad: Building Startup-Ready Communities
dugsong
0
380
Abbi's Birthday
coloredviolet
4
11k
What Being in a Rock Band Can Teach Us About Real World SEO
427marketing
0
1.1k
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