Skip to main content

[GoogleDeveloper] Reduce JavaScript Payloads with Tree Shaking

Tree Shaking 是什麼?#

Tree Shaking 這個是自從 Rollup 紅過來的,指的是把沒用到的程式碼移除(dead code elimination)。

// Import all the array utilities!import arrayUtils from 'array-utils';
// Import only some of the utilities!import { unique, implode, explode } from 'array-utils';

這兩段程式碼一個會把整個 library 載入,另一個則是只會載入有用到的函式。在開發模式下,這兩個的打包的結果會是一樣的;然而,在正式環境(production mode),可以在 webpack 中把其他沒有載入到的模組移除,讓正式環境打包出來的檔案更輕巧。

透過 Tree Shaking,只有實際上有使用到的模組(程式碼)才會出現在最後打包好的檔案。

使用 Tree Shaking#

STEP1: 讓 Babel 不編譯和模組相關的關鍵字#

由於使用 Tree Shaking 時必須讓 webpack 能夠認懂 import 這個關鍵字,因此如果我們有使用 babel 的話,需要讓 babel 不要轉譯和模組相關的關鍵字:

// .babelrc{  "presets": [    [      "env",      {        "modules": false      }    ]  ]}

當你在 babel-present-env 的設定檔 .babelrc 中加上 "modules: false" 後,webpack 就可以分析你的相依樹(dependency tree)並且移除掉沒有被使用到的套件。更進一步,這麼做並不會影響到程式碼的相容性(compatibility),因為 webpack 最後會很聰明的將你的程式碼轉換為可相同的格式。

STEP2: Webpack production mode#

當 webpack 以 production mode 執行時,即會自動執行 tree shaking 的功能:

$ npx webpack -p

或者在 webpack.config.js 的設定檔中,設定 modeproduction

module.exports = {    ...,    mode: "production",    ...,};

STEP3: 留意可能的 side effects#

side effect 指的是有些程式碼是在被 imported 的時候就執行了某些行為,而非和任何有關的 export 有關。最常見會有 side effect 的套件是 polyfill。Polyfill 通常不會在主要的 scripts 中提供 export 方法,而是要把它放到整個專案中使用。

但是 Tree shaking 沒辦法自動判斷哪些程式碼是有 side effect 的,所以必須手動告知它。例如定義在 package.json 中:

// package.json{    ...,    "sideEffects": [        "./src/polyfill.js"    ],    ...,}

Keeping Side Effects in Mind @ Google Developers

資料來源#