Webpack | 實測 Tree Shaking 針對不同 Import、Export 情境的 Bundle 結果分享
前言:
為什麼會寫這篇文章呢?因為自己先前在研究前端效能調校的時候,剛好有看到「不同的 Import 、Export 方式,對 Tree Shaking 是有影響的」,因此好奇想找找網路上有沒有各種情境下,Tree Shaking 的效果比較。
但找了一陣子都只有找到一些簡單的範例,而比較舊的文章也有可能因為 Webpack 的版本不一樣而有不同的結果,因此就想說乾脆自己用最新版的測試各種結果,然後一併分享給大家好了。
所以這篇不會說到什麼很艱深的理論部分,就是單純分享各種情況下的結果給大家參考看看。
怕有人不知道什麼是 Tree Shaking,大致介紹一下就是:「在打包過程中,刪除你沒有用到的程式碼,以減少產生出來的 bundle 體積。」
目錄
- 前置作業
- 有 Side Effects 的 Function
- 沒有 Side Effects 的 Function
- 「named export」&「default export」
- 「Class」&「非 Class」
前置作業
開始實測前,我們先建好專案以及配置好設定、環境以及結構。
結構大致如下:
webpack-test
|- /node_modules
|- /src
|- demo1
|- /dist
|- index.js // 入口文件
|- xxx.js... // 一個或多個會用到的 js 檔案
|- demo2...
|- package.json
|- webpack.config.js
再來我們根據官方文件配置一些關於 Tree Shaking 的設定:
有 Side Effects 的 Function
這裡因為 console.log 的關係造成了 Side Effects,但 Webpack 打包的結果是執行 add1 之後得到的結果 101,而不是把這個 Function 打包進去,直接優化減少了一個 Execution context。
沒有 Side Effects 的 Function
雖然 add1(100) 有被 invoked,但即使拿掉也沒任何影響,看來 Webpack 是成功移除了。
「named export」&「default export」
named export + import * as
這裡雖然 add2 不見了( 因為沒有 console.log 這個 Side Effect ),但有一點不同的是 add1( 也就是 n )被打包進去了,而且有 n(100),不像之前是完全被移除了。
named export + import { }
這裡雖然 add2 不見了( 因為沒有 console.log 這個 Side Effect ),但有一點不同的是 add1( 也就是 n )被打包進去了,而且有執行 n(100),不像之前是完全被移除了。
default export + import + function 不先包在一個物件
default export + import + function 先包在一個物件
這裡發現兩個問題:
- 用 default export 匯出,不知為何跑出了 const
- 用 default export 匯出,先包成 Object 再 export 居然會對 Tree Shaking 有影響
來一個 named export + 先包成 Object 再 export 的比對一下
可以看到似曾相似,只有 add1 存在。
第一點先不討論,但就以第二點來說,要使用 default export 似乎需要注意一下。
「Class」&「非 Class」
Class 通常都使用 「 default export」來做導出,因此這裡以此為例
Class
非 Class
以實測結果來看, 「Class」 的範例,不管 function 有沒有使用都被打包進去了,看來 Webpack 對於 Class 的 Tree Shaking 似乎是不太友善?尤其是當這個 JS 是一個龐大的函式庫,可能會打包了很多不必要的 function。
相反地,「非 Class」的範例就非常乾淨。
這裡我其實有驚訝到,因為本身原先是寫 Java 的,所以看到 ES6 有 Class 的語法糖時,就馬上在新專案裡面搞了一堆 Class 😂,沒想到測試後是這個結果。
最後總結一下自己的觀點:
- 有多個東西要 export,用 named export 加上一般的 import ( 解構 ) 比較好
- 除非只有一個東西要 export,否則不要亂用 default export,而且使用時不要先用 Object 包起來,因為 Javascript 訪問 Object’s property 的方式太多了,很難做到完整的 Tree shaking。
- 如果不是要寫 OOP,要衡量一下是否真的需要使用 Class
結論
透過這個實測發現了一些很有趣的狀況,希望這篇文章可以幫助到跟我有相同疑問的人,然後如果有說錯或是說得不好的地方再麻煩指正一下 😂,感謝大家!!