讓購物中心 Lighthouse 從 55 分到 75 分
現代網頁效能改善的美麗與哀愁
About me
陳冠霖
Jason Chen
Yahoo 購物中心前端工程師
slack: gchen02
https://fb.me/Jason.GuanLin.Chen
https://medium.com/@as790726
Comics Scroller Chrome extension
你的網頁效能好嗎
效能
- 動畫順暢程度
- 事件響應速度
- 畫面呈現速度
動畫效能
- 60 fps
- pixel pipeline
- 用 css transition transform 去防止 document reflow
- 用 requestAnimationFrame 去防止 drop frame
- debounce or throttle scrolling event
- 或是使用 IntersectionObserver
事件響應速度
- 資料結構演算法
- 最小化 virtual DOM 更新數量
- shouldComponentUpdate React.memo PureComponent
- 稍微注意 function instance
畫面呈現速度
- First Contentful Paint
- First Meaningful Paint
- Speed Index
- CPU Idle
- Time To Interactive
- Estimated input delay
Google Lighthouse audit
Simulate Slow 4G
用觀察到的正常速度網頁載入速度數據來模擬慢速網頁載入
- 跑分速度: 快
- 夠用
Applied Slow 4G
在 request 層級降速,不是封包層級降速
- 跑分速度: 慢
- 其實沒有你想像的精確 缺乏 dns tls tcp 封包等級的降速
Example 蝦皮 SPA FCP FMP
- First Contentful Paint : 瀏覽器出現畫面的瞬間
- Fitst Meaningful Paint: DOM 改變數量最多的瞬間
圖片上方面積的積分
加權
Webpagetest.org
- 免費的測速網站服務
- 封包層級降速
- 測速地點遍佈全球,新加坡東京
- real device in Dullas
- 可以錄影片做比較
- data chunk loading 視覺化呈現
瀏覽器如何載入 resource
哪個比較快
- div with background-Image
- img tag
Critical Rendering Path
- sync script 會停止 html parsing 直到之前的 css and script 載入並執行完成
- 在 CSSOM and DOM 完成以後瀏覽器才開始繪製
- html 的 parsing 不會因為 img css 的下載而停止
- 即使 parser 被 script 暫停,有一個 preload scanner 會繼續 scan 可以下載的資源
CSSOM ready
render tree
Layout
Paint
DOM ready
<html>
<head>
<link href="style.css" rel="styesheet" />
</head>
<body>
<div>
<img src="https://www.yimg.com/logo.jpg" />
<div style="background: url('https://www.yimg.com/bg.jpg')"></div>
</div>
</body>
<script async src="https://www.yimg.com/core.js"></script>
<script async src="https://www.yimg.com/verndor.js"></script>
<script async src="https://www.yimg.com/page.js"></script>
</html>
time to first byte
parsing html
download css
download img async script
DOM ready
CSSOM ready
download backgroundimage
render tree
Layout
Paint
defer or async
<script async src="https://www.yimg.com/core.js"></script>
<script async src="https://www.yimg.com/verndor.js"></script>
<script async src="https://www.yimg.com/page.js"></script>
<!-- -->
<script defer src="https://www.yimg.com/core.js"></script>
<script defer src="https://www.yimg.com/verndor.js"></script>
<script defer src="https://www.yimg.com/page.js"></script>
What happend when connect to a domain
download
DNS 391ms
TCP 154ms
TLS 192ms
Content download
TCP protocol congestion control slow start 14KB in 1st RTT
https://m.tw.buy.yahoo.com
DNS
TCP
TLS
Content
https://www.yimg.com
DNS
TCP
TLS
Content
Connection to other domain is expensive
Http/1 protocol
connection 是有限資源
- 瀏覽器最多開 6 個 connection 對同一個 domain
- image spirit
- bundle to 1 script
Http/2 protocol
- multiplexing in one connection
CSS stream
JS stream
img stream
http/2 multiplexing
https://www.yimg.com
DNS
TCP
TLS
Content
css
img
script
font
DNS
TCP
TLS
css
img
script
font
DNS
TCP
TLS
css
img
script
font
FCP🚀
FCP🐢
Http/2 prioritization
- parent stream
- weight
- exclusive bit
Http/2 prioritization
Parent Stream
Http/2 prioritization
weight
Bandwidth
Http/2 prioritization
exclusive bit
Bandwidth
不同的瀏覽器
不同的 Prioritization implementation
Chrome prioritization
- exclusive bit in every resource
Chrome prioritization
Chrome prioritization
Firefox prioritization
- Grouping resource
- flower loading after leader
Firefox prioritization
Firefox prioritization
Safari prioritization
- no dependencies
- share bandwidth based on weight
Safari prioritization
Safari prioritization
IE Edge Prioritization
- no prioritization
IE Edge Prioritization
IE Edge Prioritization
Browser Comparison
更糟糕的是 😱 !
很多的 CDN Servers prioritization 也是壞掉的
用 webpagetest 來做一個簡單的實驗
http2 prioritization is broken even for Google Amazon Azure
Yimg is broken too
http/2 的挑戰
- connection 對 new domain 是昂貴的
- http2 prioritization 在 client side 不完美
- http2 prioritization 在 server side 也不完美
改善網頁載入速度策略
inline critical css
<style>
.header {
}
.banner {
}
.rushBuy {
}
</style>
<link
href="https://yimg.com/noncritical.css"
rel="preload"
onload="this.onload=null;this.rel='stylesheet'"
as="style"
/>
如何找到 critical style
- penthouse
- 用 headless chrome 去爬 style 並比較 DOM node 有沒有在 viewport
- Problems
- timeout base DOM
- cookie base DOM
- localstorage base DOM
- API base DOM
inline all your css
https://m.tw.buy.yahoo.com
DNS
TCP
TLS
Content
https://www.yimg.com/style.css
DNS
TCP
TLS
Content
https://m.tw.buy.yahoo.com
DNS
TCP
TLS
inline style in html
Browser Cache ?
最佳解 CSS in JS ?
preload hero background img and
preconnect domain
- css Object fit IE 不支援 只好繼續 background Image
- <link rel="preload" as="image" href="./img.jpg" />
- DO NOT preload everything
- dns prefecth preconnect 偷偷先建立連線 減少 connection 的成本
- dns prefetch 的支援度比較高
Lazyload img carousel and module
- <img loading="lazy"> only for latest chrome
- 用 IntersectionObserver and polyfill 作為替代
element in html 比 element paint in script 來得快
- 🐢 localstorage CSR AD
- 🚀 cookie SSR AD
- 🐢 svg icon in script
- 🚀 svg in html
改善效能的成果
Chrome audit with Lighthouse
Webpagetest in Tokyo 3G
我們的網站有比較快嗎
但是做了這麼多努力Taiwan 多少人還在用 3G 上網?
跑分跟真實使用者體驗的差別
- Lab data
- Field data
Chrome User Experience Report
- chrome 會偷偷搜集網頁加載速度的資訊回傳給 Google
- time to first Byte
- first paint
- first contentful paint
- connection type
- 根據 domain 的統計數據
Page Speed Insight
Google Big Query
Chrome ux dashboard by google data studio
g.co/chromeuxdash
Taiwan 多少人還在用 3G 上網?
5 %
努力徒勞無功?
First Contentful Paint
Fast < 1s , 1< Avg < 2.5s, slow > 2.5s
7/18
上線
fast + 12.35 %
slow - 34.65 %
onload
Fast < 2.5s , 2.5 < Avg < 6.5s, slow > 6.5s
7/18
上線
fast + 12.45 %
slow - 26.21 %
Crux.run
- 更細的分佈圖
- 跑得快
現代網頁效能改善的美麗與哀愁
所以我們網站是快的嘛
API response 的時間也很重要
Bundle size
- tree shaking
- lazyload component
- code split
- atomic css
- lodash bable plugin
Performance is a culture
Learning Moments
- connection 到另外 domain 是昂貴的
- 理解 http/2 prioritization 的原理
- http/2 prioritization 瀏覽器跟 CDN 常常有很多的不完美
- 所以 inline style 對 lighthouse 跑分很有效
- lazyload 跟 link preload
-
值得一試 Lab data Tool
- webpagetest.org
- lighthouse
- 量化你改善效能的成果 Field data Tool
- g.co/chromeuxdash
- crux.run
- Performance is a culture
Resource
讓購物中心 Lighthouse 從 55 分到 75 分 現代網頁效能改善的美麗與哀愁
By zeroshine
讓購物中心 Lighthouse 從 55 分到 75 分 現代網頁效能改善的美麗與哀愁
- 388