2020年10月19日 星期一

[JS] 你的 JS 該減肥了!5個提升網頁載入速度的技巧

 

1. 優化網頁載入速度

為什麼要加快載入速度

  • 載入速度=使用者體驗
  • 根據Amazon內部統計,慢100ms=營收減少1%
  • SEO

第一步:善用測速工具

如何決定優化的優先順序

  • 修正以後改善最多的項目
  • 業務範圍中最容易改動的部分
  • 先做出成果,┬得到主管信任,爭取更多優化空間
  • 例:優化圖片尺寸,涉及 app 上傳 / 後端處理
  • 例:優化JavaScript bundle 體積,前端可自己修改 build 設定 (優先優化圖片尺寸)

2. 我的JS很肥會怎樣嗎?

瀏覽器運作原理

  • 結論:JS bundle越大,網頁載入越慢
  • 瀏覽器:解析HTML > 建立DOM TREE > 渲染頁面
  • JS “blocks” DOM tree 的建立過程
  • 下載 + 執行 JS 越慢,block 越久,越慢渲染畫面

Code Splitting

  • 將單一JS檔案拆分成許多小塊
  • 平行載入
  • 有需要時才載入

3. 拆分出Vendor Bundle

  • Webpack runtime and manifest: 負責模組之間互動,體積可忽略不計
  • Application Bundle: UI /商業邏輯,經常變動
  • Vendor Bundle: 第三方套件 /node_modules,不太變動

Why Vendor Bundle?

  • 通常變動不頻繁
  • 可被快取
  • 此配置在有 cache 情況下載入更快

未優化Bundle的規劃

桌機版手機版說明
arcade.js585KB426KB商業邏輯
omlib.js205KB205KB內部 lib/ API
vendor.js366KB366KB第三方套件
sum1156KB997KB

運用工具分析配置是否合理

  • 運⽤ webpack-bundle-analyzer 作視覺化分析
  • application bundle
    • 裡⾯有 node_modules
    • 併入 vendor bundle 更好

取出 Vendor bundle

  • 將 node_modules 統一打包成vendor.js
  • 結果
桌機版手機版說明
arcade.js585KB 310KB426KB 218KB商業邏輯
omlib.js205KB205KB內部 lib/ API規格
vendor.js366KB 632KB366KB 632KB第三方套件
sum1156KB997KB1055KB*

效果:減少 application bundle 的⼤⼩,加快再訪者載入速度

4. Dynamic Loading

  • 對新用戶而言,網站整體大小不變
  • 如何減少整體下載量?動態下載需要的模組
  • ⽤到某段程式碼的時候才透過網路下載 JS bundle

ESM import()

  • Webpack 支援 ESM import() 語法實現 dynamic import

根據路徑做 Dynamic Import

  • 為何根據路徑?
    • GA數據顯⽰使⽤者⼤多停留在熱⾨⾴⾯,換⾴次數少
  • react-router ⽀援 dynamic import
桌機版手機版說明
arcade.js310KB 235KB218KB 189KB商業邏輯
omlib.js205KB205KB第三方套件
vendor.js632KB632KB內部 lib/ API規格
sum1156KB 1072KB*1055KB 1026KB** 體積最⼤的⾸⾴~20KB

效果:減少 application bundle 下載量

對肥大套件做 Dynamic import

  • 那些套件適合 dynamic import?
    • 很肥大
    • 使用頻率低
    • eg. JSZip (27KB), moment.js (64KB), request (70KB), hls.js (77KB)
  • 結果
桌機版手機版說明
arcade.js235KB189KB商業邏輯
omlib.js205KB205KB內部 lib/ API規格
vendor.js632KB 267KB632KB 267KB第三方套件
sum1072KB 784KB*1026KB 707KB** 以使⽤頻率最 ⾼的⾸⾴為例

效果:⼤幅減少整體下載量

Tree-Shaking

  • 將沒有用到的程式碼從 JS bundle 中移除
  • 必須使用 ESM import/export (靜態結構)

如何設定 Tree-shaking

  • 將專案中 CommonJS 的 require/module.exports 語法改寫成 ES Module 的 import/export 語法
  • 在 package.json 中標示具有 side effets 的模組(例如CSS)
  • 結果
桌機版手機版說明
arcade.js235KB189KB商業邏輯
omlib.js205KB 87KB205KB 87KB內部 lib/ API規格
vendor.js267KB267KB第三方套件
sum784KB 666KB*707KB 589KB*

效果:⼤幅減少整體下載量

5. 其他小技巧

第三方套件使用 CDN 版本

  • 經常被使用的第三方套件 eg. React/jQuery
  • 容易被快取
  • react-dom: 36KB

使用 preset-env 減少 Polyfill 體積

  • Polyfill: 讓舊的瀏覽器也能支援新的 API
  • preset-env: preset-2015 的加強版
    • preset: babel-loader的語法 plugin 集合
    • 根據支援瀏覽器清單,自動引入polyfill
    • 結果:31KB 18KB
  • 最終結果
桌機版手機版說明
arcade.js585KB 235KB426KB 189KB商業邏輯
omlib.js205KB 87KB205KB 87KB內部 lib/ API規格
vendor.js366KB 267KB366KB 267KB第三方套件
sum1156KB 666KB(-43%)997KB 589KB* (-41%)

根據 GA 數據,平均載入所需時間減少 30%

結論

  • 拆分出 vendor bundle
  • 根據路徑做 dynamic import
  • 對肥大第三方套件做 dynamic import
  • 使用 tree shaking 移除沒用到的程式碼
  • 熱門第三方套件使用 CDN 版本
  • 使用 preset-env 減少 Polyfill 體積

以上內容轉載自『Modern Web 2020 共筆

沒有留言:

張貼留言

Google Analytics初學者入門簡介