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
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
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
670
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.2k
日経電子版のマイクロフロントエンドとPWA / devsum2019
shqld
8
13k
Other Decks in Technology
See All in Technology
Introduction to Sansan for Engineers / エンジニア向け会社紹介
sansan33
PRO
6
77k
Oracle AI Databaseデータベース・サービス: BaseDB/ExaDB-Dの可用性
oracle4engineer
PRO
1
910
暗号化?某ファイルストレージはどうなるの!? 3rd Partyとうまく付き合う秘密度ラベル設計
kasada
0
200
Master Dataグループ紹介資料
sansan33
PRO
1
4.8k
名刺メーカーDevグループ 紹介資料
sansan33
PRO
0
1.2k
コミュニティから始まった農業IoTとの7年間 ——人との関わりが教えてくれたこと
peacemaker07
0
110
サイボウズ 開発本部採用ピッチ / Cybozu Engineer Recruit
cybozuinsideout
PRO
12
85k
RapidCopy2 Matrix I/Oエンジンによるファイルコピーソフトウェアの設計と実装
kengosawa2
1
410
OpenID for Verifiable Credentials 実装から見えた相互運用性確保までの道のり(OAuth/OIDC Numa (Immersion) Workshop 2026)
oidfj
PRO
0
280
Oracle MCP Servers Explained
thatjeffsmith
1
510
英語が話せなくてもKubeConスタッフに参加した話
yusuke427
2
1.1k
dbt と Snowflake と tag
kevinrobot34
1
250
Featured
See All Featured
Site-Speed That Sticks
csswizardry
13
1.5k
Visual Storytelling: How to be a Superhuman Communicator
reverentgeek
2
620
Applied NLP in the Age of Generative AI
inesmontani
PRO
4
2.4k
The Spectacular Lies of Maps
axbom
PRO
1
940
Fireside Chat
paigeccino
42
4k
The Cult of Friendly URLs
andyhume
79
7k
Keith and Marios Guide to Fast Websites
keithpitt
413
23k
JAMstack: Web Apps at Ludicrous Speed - All Things Open 2022
reverentgeek
1
580
Measuring & Analyzing Core Web Vitals
bluesmoon
9
970
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
49
10k
Collaborative Software Design: How to facilitate domain modelling decisions
baasie
1
290
Breaking role norms: Why Content Design is so much more than writing copy - Taylor Woolridge
uxyall
1
380
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