不折騰的前端,和鹹魚有什麼區別css
目錄 |
---|
一 目錄 |
二 前言 |
三 什麼是 dead-code ? |
四 什麼是反作用? |
五 如何作到 Tree Shaking ? |
六 總結 |
七 其餘問題 |
7.1 提問 1:爲何能夠實現 Tree Shaking? |
7.2 提問 2:下面哪一種狀況會 Tree Shaking? |
返回目錄
Tree Shaking
是 Webpack
內置的一個優化,主要功能是移除 JavaScript 上下文中的未引用代碼(dead-code
)。前端
由於 JavaScript 大多數文件是要經過網絡引用加載的,加載的文件越小,性能越好,因此 Tree Shaking
對於優化 JavaScript 頗有意義。webpack
你能夠將引用程序想象成一棵樹,而後裏面有枯死的樹葉和新鮮的樹葉,你搖動它,枯死的樹葉紛紛落下,你就看到一棵生機盎然的樹。git
dead-code
?返回目錄
即 JavaScript 上下文中的未引用代碼(無用的,死的代碼)。github
舉個例子:web
project category
webpack-demo |- index.js |- main.js
main.js
export function square(x) { return x * x; } export function cube(x) { return x * x * x; }
index.js
import { cube } from './main.js'; const result = cube(5); const p = document.querySelector('.p'); p.innerHTML = result;
在這裏,咱們並無引用方法 square
,因此總體來講 square
是未引用代碼(dead-code
),可是 Webpack 打包的時候會將 square
導出到 bundle
中。json
返回目錄
反作用是指:在導入時會執行特殊行爲的代碼,而不是僅僅暴露一個 export
或者多個 export
。數組
舉個例子:polyfill
它影響全局做用域,而且一般不提供 export
。安全
Tree Shaking
?返回目錄
在 Webpack 中,作到 Tree Shaking
的方法就是將一些文件標明爲無反作用,這樣就能夠告知 Webpack 它能夠安全地刪除未用到的 export
導出。網絡
package.json
{ "name": "jsliang-project", "sideEffects": false }
像上面,經過在 package.json
中定義 sideEffects
屬性,就能夠將文件標記爲無反作用。
固然,若是有些文件你怕它有反作用,那就告知 Webpack 其中某些文件不須要標記:
package.json
{ "name": "jsliang-project", "sideEffects": [ "./src/math.js", "*.css*", ] }
這裏能夠經過一個數組,數組支持 相關文件的相對路徑、絕對路徑和 glob
模式。
這樣,咱們就找出了 未使用代碼(dead-code
)。
可是正如上面所說,只是告知,並無刪除。
若是咱們須要在 bundle
中刪除它們,就須要使用 -p
(production
)這個 Webpack 編譯標記,來啓用 uglifyjs
壓縮插件。
注意:--optimize-minimize
標記也會在 Webpack 內部調用UglifyJSPlugin
。webpack.config.js
const path = require('path'); module.exports = { entry: './src/index.js', output: { filename: 'bundle.js', path: path.resolve(__dirname, 'dist') }, mode: "production" };
返回目錄
爲了達到 Tree Shaking
的做用,你須要:
import
和 export
。package.json
文件中,添加 sideEffects
入口。dead-code
)的壓縮工具(例如 UglifyJSPlugin
)返回目錄
返回目錄
ES6 模塊依賴關係是肯定的,和運行時的狀態無關,能夠進行可靠的靜態分析,這就是 Tree Shaking
的基礎。
所謂的 靜態分析,就是不執行代碼,從字面量上對代碼進行分析,ES6 以前的模塊化,好比咱們能夠動態 require
一個模塊,只有執行後才知道引用的什麼模塊,這個就不能經過靜態分析去作優化。
// demo.js export const a = 'a'; export const b = 'b'; // test.js import { a } from './demo.js'; // 以上代碼不運行,僅僅通過掃描分析,拋棄了 const b,代碼縮減了 size // 這就是 Tree Shaking 的靜態分析基本原理:有引用就保留,沒有引用就拋棄
因此爲啥 CommonJS 不能 Tree Shaking
就是這個緣故。
返回目錄
// 所有導入 import _ from 'lodash'; // 具名導入 import { debounce } from 'lodash'; // 直接導入具體模塊 import debounce from 'lodash/lib/debounce';
上面導入中:第一種的 所有導入 是不支持 Tree Shaking
的,其餘都支持。
爲何呢?由於當你將整個庫導入到單個 JavaScript 對象中時,就意味着你告訴 Webpack,你須要整個庫,這樣 Webpack 就不會搖它。
jsliang 的文檔庫由 梁峻榮 採用 知識共享 署名-非商業性使用-相同方式共享 4.0 國際 許可協議 進行許可。<br/>基於 https://github.com/LiangJunrong/document-library 上的做品創做。<br/>本許可協議受權以外的使用權限能夠從 https://creativecommons.org/licenses/by-nc-sa/2.5/cn/ 處得到。