1. 優化網頁載入速度
為什麼要加快載入速度
第一步:善用測速工具
如何決定優化的優先順序
- 修正以後改善最多的項目
- 業務範圍中最容易改動的部分
- 先做出成果,┬得到主管信任,爭取更多優化空間
- 例:優化圖片尺寸,涉及 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.js | 585KB | 426KB | 商業邏輯 |
omlib.js | 205KB | 205KB | 內部 lib/ API |
vendor.js | 366KB | 366KB | 第三方套件 |
sum | 1156KB | 997KB |
運用工具分析配置是否合理
- 運⽤ webpack-bundle-analyzer 作視覺化分析
- application bundle
- 裡⾯有 node_modules
- 併入 vendor bundle 更好
取出 Vendor bundle
- 將 node_modules 統一打包成vendor.js
- 結果
桌機版 | 手機版 | 說明 | |
---|---|---|---|
arcade.js | 商業邏輯 | ||
omlib.js | 205KB | 205KB | 內部 lib/ API規格 |
vendor.js | 第三方套件 | ||
sum | 1156KB |
效果:減少 application bundle 的⼤⼩,加快再訪者載入速度
4. Dynamic Loading
- 對新用戶而言,網站整體大小不變
- 如何減少整體下載量?動態下載需要的模組
- ⽤到某段程式碼的時候才透過網路下載 JS bundle
ESM import()
- Webpack 支援 ESM import() 語法實現 dynamic import
根據路徑做 Dynamic Import
- 為何根據路徑?
- GA數據顯⽰使⽤者⼤多停留在熱⾨⾴⾯,換⾴次數少
- react-router ⽀援 dynamic import
桌機版 | 手機版 | 說明 | |
---|---|---|---|
arcade.js | 商業邏輯 | ||
omlib.js | 205KB | 205KB | 第三方套件 |
vendor.js | 632KB | 632KB | 內部 lib/ API規格 |
sum | * 體積最⼤的⾸⾴~20KB |
效果:減少 application bundle 下載量
對肥大套件做 Dynamic import
- 那些套件適合 dynamic import?
- 很肥大
- 使用頻率低
- eg. JSZip (27KB), moment.js (64KB), request (70KB), hls.js (77KB)
- 結果
桌機版 | 手機版 | 說明 | |
---|---|---|---|
arcade.js | 235KB | 189KB | 商業邏輯 |
omlib.js | 205KB | 205KB | 內部 lib/ API規格 |
vendor.js | 第三方套件 | ||
sum | * 以使⽤頻率最 ⾼的⾸⾴為例 |
效果:⼤幅減少整體下載量
Tree-Shaking
- 將沒有用到的程式碼從 JS bundle 中移除
- 必須使用 ESM import/export (靜態結構)
如何設定 Tree-shaking
- 將專案中 CommonJS 的 require/module.exports 語法改寫成 ES Module 的 import/export 語法
- 在 package.json 中標示具有 side effets 的模組(例如CSS)
- 結果
桌機版 | 手機版 | 說明 | |
---|---|---|---|
arcade.js | 235KB | 189KB | 商業邏輯 |
omlib.js | 內部 lib/ API規格 | ||
vendor.js | 267KB | 267KB | 第三方套件 |
sum |
效果:⼤幅減少整體下載量
5. 其他小技巧
第三方套件使用 CDN 版本
- 經常被使用的第三方套件 eg. React/jQuery
- 容易被快取
- react-dom: 36KB
使用 preset-env 減少 Polyfill 體積
- Polyfill: 讓舊的瀏覽器也能支援新的 API
- preset-env: preset-2015 的加強版
- preset: babel-loader的語法 plugin 集合
- 根據支援瀏覽器清單,自動引入polyfill
- 結果:
31KB18KB
- 最終結果
桌機版 | 手機版 | 說明 | |
---|---|---|---|
arcade.js | 商業邏輯 | ||
omlib.js | 內部 lib/ API規格 | ||
vendor.js | 第三方套件 | ||
sum |
根據 GA 數據,平均載入所需時間減少 30%
結論
- 拆分出 vendor bundle
- 根據路徑做 dynamic import
- 對肥大第三方套件做 dynamic import
- 使用 tree shaking 移除沒用到的程式碼
- 熱門第三方套件使用 CDN 版本
- 使用 preset-env 減少 Polyfill 體積
以上內容轉載自『Modern Web 2020 共筆』
沒有留言:
張貼留言