Web Frontend Optimization

這邊的 Optimization 將會 focus 在 減少使用者等待的時間 以及 保持 Web App 操作上的效能 這兩個部分,各自對應到兩個種類: 與 Loading 相關的優化 以及 與 Rendering 相關的優化

與 Loading 相關的優化

壓縮資源

> 圖片壓縮

> 程式碼壓縮

減少 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

Lazy loading

> Data

  • Scroll to fetch

> Page (or Component)

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 時, 即停止
  • Compare with CSS-based animation - reference by MDN - CSS and JavaScript animation performance

    The fact is that, in most cases, the performance of CSS-based animations is almost the same as JavaScripted animations

    This 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 is done in the GPU, meaning better performance/efficiency, especially on mobile

Web worker

利用 Web worker 來跑一些比較複雜運算

參考文獻