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
680
High Performance JavaScript / jsconfjp2019
shqld
0
640
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
AgentCoreで実践するハーネスエンジニアリング
yakumo
1
290
AIは爆速なのに、私が詰まっていた話 ― 音声入力と鳴くマスコットでボトルネックを削る
yama3133
0
580
継続的なAIコスト最適化
bgpat
1
270
今さら理解するウェブフォントver.2026
takanorip
3
570
OR学会2026年秋期大会_機械学習と数理最適化の融合による、配合レシピ最適化システム開発事例
brainpadpr
0
110
AI時代のAPI開発を加速する品質ガードレール / API Quality Guardrails in the AI Era
yokawasa
0
170
ハードウェアコンペでもAI駆動開発が進んでいる話
iotengineer22
1
660
分析AIエージェントを育てる、動く環境を育てる
codatum
1
720
メルペイ 会計システム概要と歴史
mewuto
0
200
生成AIと進める探索的データ分析(2026.10.03 第122回Tokyo.R勉強会)
tatamiya
2
1.5k
並行性の問題を防げ!実践トランザクション入門
occhi
0
280
「事実」を「計測」して、「解釈」する 〜AWS Lambdaのメモリ最適解の見つけ方〜
maimyyym
0
120
Featured
See All Featured
The browser strikes back
jonoalderson
0
1.8k
Designing for humans not robots
tammielis
254
26k
Money Talks: Using Revenue to Get Sh*t Done
nikkihalliwell
0
510
The AI Search Optimization Roadmap by Aleyda Solis
aleyda
2
6.3k
4 Signs Your Business is Dying
shpigford
187
23k
SERP Conf. Vienna - Web Accessibility: Optimizing for Inclusivity and SEO
sarafernandez
2
1.6k
Building a Scalable Design System with Sketch
lauravandoore
464
34k
Intergalactic Javascript Robots from Outer Space
tanoku
273
27k
Conquering PDFs: document understanding beyond plain text
inesmontani
PRO
4
3.2k
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
46
3k
Navigating Team Friction
lara
192
16k
How to Ace a Technical Interview
jacobian
280
24k
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