這邊的 Optimization 將會 focus 在 減少使用者等待的時間
以及 保持 Web App 操作上的效能
這兩個部分,各自對應到兩個種類: 與 Loading 相關的優化
以及 與 Rendering 相關的優化
與 Loading 相關的優化
壓縮資源
> 圖片壓縮
> 程式碼壓縮
- Remove unused code
- webpack - tree-shaking(dead-code elimination)
- Remove comment
- Minify
減少 Request 數量
> CSS sprite
將圖檔合併成一張圖, 再利用 CSS 技巧去擷取需要的部分 (e.g. 調控 background-position)
Background loading - 避免 block main thread
> async/defer in <script> tag
- async: script download in background, 當 script 載回來後才去執行 script 內容
- defer: script download in background, 當 html parse 完, 在
DOMContentLoaded
前執行
> partial data fetching
- The case I meet: Leaderboard in campaign page
- 後端抓資料的 API 支援
pagination
- Before:
一次拉完
所有 pages 後才 render 出 board, 當資料量大時會導致等待時間過長
- After:
拉多少就 render 多少
, 當拉到資料後去 re-render board
- 後端抓資料的 API 支援
Lazy loading
> Data
- Scroll to fetch
> Page (or Component)
- 搭配
Code splitting
- React.lazy
HTTP Cache
將一些檔案 Cache 再 client 中, 省去和 Server 重複要資料(e.g. 重新整理時)
> HTTP response header params (set by Web server)
Cache-control: max-age=XXXX
- 當一個資源在這個 max-age 內(e.g. max-age=10, 也就是收到此 Http reponse 10 秒內), 當 user 因為重整或再次造訪網頁時, 都會直接跟 cache 拿而不發 request 到 server
- 循序漸進理解 HTTP Cache 機制
CDN (Content Delivery Network)
Client 會和物理距離其較近的的 Server 要資料 => 縮短了 response(resources) 送到 client 的時間
與 Rendering 相關的優化
lazy rendering
只 render viewport 內的 element, e.g. react-window, react-virtualized
Avoid unecessary re-render/re-mount
> Avoid unecessary re-render (in react VDOM)
- React.memo, PureComponent APIs
- useCallback, useMemo APIs
> Avoid unecessary re-mount
React 有的 VDOM 機制來協助我們避免不必要的 re-mount
Animation in JS
> requireAnimationFrame(callback) API
- 在每一次 re-paint 之前, 都會 run 一次 callback
Compare with animate by
setInterval
API- setInterval
- 需要去設定每個 interval 的間隔, 當設定的間隔小於 device 的 FPS, 會導致畫面不流暢以及消耗不必要的效能
- 當 browser 切換 tab 或最小化時, 會
持續在背景執行
, 不會停止, 浪費不必要的 CPU 資源以及電池資源
- raf
- interval 為
每一次 browser re-paint 的間隔
, 會隨著 device 不同而定 - 當 browser 切換 tab 時, 即停止
- interval 為
- setInterval
Compare with
CSS-based animation
- reference by MDN - CSS and JavaScript animation performanceThe fact is that, in most cases, the performance of CSS-based animations is
almost the same
as JavaScripted animationsThis can occur because CSS transitions/animations are simply resampling element styles in the
main UI thread
before each repaint event happens, which is almost the same as resampling element styles via a requestAnimationFrame() callback, also triggered before the next repaint什麼時候 CSS-based animation 會表現較好 ?
As long as the properties we want to animate
do not trigger reflow/repaint
- e.g. Animate by
transform
property will not trigger reflow/repaint, which isdone in the GPU
, meaning better performance/efficiency, especially on mobile
- e.g. Animate by
Web worker
利用 Web worker 來跑一些比較複雜運算