webpack實戰——打包優化【下】

前言

這是webpack打包優化【下】篇。前幾篇針對性能要求高的項目從加快打包速度、減小資源體積方面入手,提出了一些優化政策,然後測試都可起到一定優化效果。本篇描述死代碼的檢測與去除

tree shaking

1 死代碼檢測去除

首先拋出問題,什麼是死代碼?

工程中沒有被引用過的模塊,這部分代碼將永遠無法被執行,稱爲“死代碼”。

那知道了什麼是死代碼,如何檢測去除呢?

在前面我們介紹過,ES6 module 依賴關係的構建是在代碼編譯時而非運行時。基於這項特性webpack提供了tree shaking功能。這個功能便可以在打包過程中幫助我們檢測沒有被引用的模塊,然後對這部分代碼進行標記,並在資源壓縮時將它們從最終的bundle中去掉

例:

// index.js
import { foo } from './util';
foo();
// util.js
export function foo() {
    console.log('this is foo');
}
export function bar() { // 沒有被任何其他模塊引用,因此屬於死代碼
    console.log('this is bar');
}

那麼在webpack打包時就會對bar()添加一個標記,在正常本地開發環境下它依然會存在,但是在生產環境壓縮資源那一環節則會被移除掉。

tree shaking有時可以使得bundle資源體積顯著減小,但需要一些前提條件。

2 ES6 Module

tree shaking 只對ES6 Module生效。 有時候我們發現算只引用了某個庫中的一個接口,卻把整個庫都加載了進來,使得bundle體積並沒有什麼變化,可能原因是該庫是用CommonJS導出的,而不是ES6 Module。當然,爲了更好地向下兼容,自然是使用CommonJS形式是庫依然很多。而排開第三方庫,在我們自己書寫模塊或者庫時,可以儘可能的選擇ES6 Module形式導出,這樣tree shaking的效率會更高。

3 使用webpack進行依賴關係構建

一般我們都會在工程中使用到babel-loader,如果我們有使用到,那麼一定要通過禁止它的模塊依賴解析。原因是如果我們使用babel-loader來做依賴解析,那麼webpack接收到的一般都是轉化過的CommonJS形式的模塊,那就無法對其進行tree shaking。

禁用babel-loader模塊依賴解析配置如下:

// webpack.config.js
module.exports = {
    ...
    module: {
        ryles: [
            {
                test: /\.js$/,
                exclude: /node_modules/,
                use: [
                    {
                        loader: 'babel-loader',
                        options: {
                            presets: [
                                // 在這裏加上modules: false
                                [@babel/preset-env, { modules: false }]
                            ]
                        }
                    }
                ]
            }
        ]
    }
}

4. 使用壓縮工具去除死代碼

tree shaking本身只是爲死代碼添加上標記,而真正意義上去除死代碼則是通過壓縮工具來進行的,而此工具之前介紹過:terser-webpack-plugin。在此不再贅述。

小結

通過【上】【中】【下】三篇描述,介紹的一些打包優化的方案均可以對項目有不同程度的優化,無論是打包速度還是減小資源體積,都有涉及。然而我們更需要清楚地瞭解到每一種優化策略都有其使用場景,並不是任何一個點放在一切項目中都有效。

當然,我們更需要不斷培養自己的能力,當發現性能問題時,根據現有情況自己多加思考,分析出原因,然後對症下藥。

下一篇介紹更多的JavaScript打包工具。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章