Vue項目Webpack優化實踐,構建效率提高50%

Vue項目Webpack優化實踐,構建效率提高50%

Webpack

公司的前端項目使用Vue框架,Vue框架使用Webpack進行構建,隨著項目不斷迭代,項目逐漸變得龐大,然而項目的構建速度隨之變得緩慢,於是對Webpack構建進行優化變得刻不容緩。經過不斷的摸索和實踐,通過以下方法優化後,項目的構建速度提高了50%。現將相關優化方法進行總結分享。

1、縮小文件的搜索範圍

1.1、優化Loader配置

由於Loader對文件的轉換操作很耗時,所以需要讓儘可能少的文件被Loader處理。我們可以通過以下3方面優化Loader配置:(1)優化正則匹配(2)通過cacheDirectory選項開啟緩存(3)通過include、exclude來減少被處理的文件。實踐如下:

項目原配置:

Vue項目Webpack優化實踐,構建效率提高50%

項目原配置

優化後配置:

Vue項目Webpack優化實踐,構建效率提高50%

優化後配置

1.2、優化resolve.modules配置

resolve.modules 用於配置Webpack去哪些目錄下尋找第三方模塊。resolve.modules的默認值是[node modules],含義是先去當前目錄的/node modules目錄下去找我們想找的模塊,如果沒找到,就去上一級目錄../node modules中找,再沒有就去../ .. /node modules中找,以此類推,這和Node.js的模塊尋找機制很相似。當安裝的第三方模塊都放在項目根目錄的./node modules目錄下時,就沒有必要按照默認的方式去一層層地尋找,可以指明存放第三方模塊的絕對路徑,以減少尋找。

優化後配置:

Vue項目Webpack優化實踐,構建效率提高50%

優化後配置

1.3、優化resolve.alias配置

resolve.alias配置項通過別名來將原導入路徑映射成一個新的導入路徑。

項目中的配置使用:

Vue項目Webpack優化實踐,構建效率提高50%

項目中的配置使用

1.4、優化resolve.extensions配置

在導入語句沒帶文件後綴時,Webpack 會在自動帶上後綴後去嘗試詢問文件是否存在。默認是:extensions :[‘. js ‘,’. json ’] 。也就是說,當遇到require ( '. /data ’)這樣的導入語句時,Webpack會先去尋找./data .js 文件,如果該文件不存在,就去尋找./data.json 文件,如果還是找不到就報錯。如果這個列表越長,或者正確的後綴越往後,就會造成嘗試的次數越多,所以 resolve .extensions 的配置也會影響到構建的性能。

優化措施:

• 後綴嘗試列表要儘可能小,不要將項目中不可能存在的情況寫到後綴嘗試列表中。

• 頻率出現最高的文件後綴要優先放在最前面,以做到儘快退出尋找過程。

• 在源碼中寫導入語句時,要儘可能帶上後綴,從而可以避免尋找過程。例如在確定的情況下將 require(’. /data ’)寫成require(’. /data.json ’),可以結合enforceExtension 和 enforceModuleExtension開啟使用來強制開發者遵守這條優化

1.5、優化resolve.noParse配置

noParse配置項可以讓Webpack忽略對部分沒采用模塊化的文件的遞歸解析和處理,這 樣做的好處是能提高構建性能。原因是一些庫如jQuery、ChartJS 龐大又沒有采用模塊化標準,讓Webpack去解析這些文件既耗時又沒有意義。 noParse是可選的配置項,類型需要是RegExp 、[RegExp]、function中的一種。例如,若想要忽略jQuery 、ChartJS ,則優化配置如下:

Vue項目Webpack優化實踐,構建效率提高50%

2、減少冗餘代碼

babel-plugin-transform-runtime 是Babel官方提供的一個插件,作用是減少冗餘的代碼 。 Babel在將ES6代碼轉換成ES5代碼時,通常需要一些由ES5編寫的輔助函數來完成新語法的實現,例如在轉換 class extent 語法時會在轉換後的 ES5 代碼裡注入 extent 輔助函數用於實現繼承。babel-plugin-transform-runtime會將相關輔助函數進行替換成導入語句,從而減小babel編譯出來的代碼的文件大小。

3、使用HappyPack多進程解析和處理文件

由於有大量文件需要解析和處理,所以構建是文件讀寫和計算密集型的操作,特別是當文件數量變多後,Webpack構建慢的問題會顯得更為嚴重。運行在 Node.之上的Webpack是單線程模型的,也就是說Webpack需要一個一個地處理任務,不能同時處理多個任務。Happy Pack ( https://github.com/amireh/happypack )就能讓Webpack做到這一點,它將任務分解給多個子進程去併發執行,子進程處理完後再將結果發送給主進程。

項目中HappyPack使用配置:

(1)HappyPack插件安裝:
Vue項目Webpack優化實踐,構建效率提高50%

(2)webpack.base.conf.js 文件對module.rules進行配置
Vue項目Webpack優化實踐,構建效率提高50%

webpack.base.conf.js

(3)webpack.prod.conf.js 文件進行配置 const HappyPack = require('happypack');
Vue項目Webpack優化實踐,構建效率提高50%

webpack.prod.conf.js

4、使用ParallelUglifyPlugin多進程壓縮代碼文件

由於壓縮JavaScript 代碼時,需要先將代碼解析成用 Object 抽象表示的 AST 語法樹,再去應用各種規則分析和處理AST ,所以導致這個過程的計算量巨大,耗時非常多。當Webpack有多個JavaScript 文件需要輸出和壓縮時,原本會使用UglifyJS去一個一個壓縮再輸出,但是ParallelUglifyPlugin會開啟多個子進程,將對多個文件的壓縮工作分配給多個子進程去完成,每個子進程其實還是通過UglifyJS去壓縮代碼,但是變成了並行執行。所以 ParallelUglify Plugin能更快地完成對多個文件的壓縮工作。

項目中ParallelUglifyPlugin使用配置:

(1)ParallelUglifyPlugin插件安裝:
Vue項目Webpack優化實踐,構建效率提高50%

ParallelUglifyPlugin插件安裝

(2)webpack.prod.conf.js 文件進行配置
Vue項目Webpack優化實踐,構建效率提高50%

webpack.prod.conf.js

5、使用自動刷新

藉助自動化的手段,在監聽到本地源碼文件發生變化時,自動重新構建出可運行的代碼後再控制瀏覽器刷新。Webpack將這些功能都內置了,並且提供了多種方案供我們選擇。

項目中自動刷新的配置:

Vue項目Webpack優化實踐,構建效率提高50%

項目中自動刷新的配置

相關優化措施:

(1)配置忽略一些不監聽的一些文件,如:node_modules。

(2)watchOptions.aggregateTirneout 的值越大性能越好,因為這能降低重新構建的頻率。

(3) watchOptions.poll 的值越小越好,因為這能降低檢查的頻率

6、開啟模塊熱替換

DevServer 還支持一種叫做模塊熱替換( Hot Module Replacement )的技術可在不刷新整個網頁的情況下做到超靈敏實時預覽。原理是在一個源碼發生變化時,只需重新編譯發生變化的模塊,再用新輸出的模塊替換掉瀏覽器中對應的老模塊 。模塊熱替換技術在很大程度上提升了開發效率和體驗 。

項目中模塊熱替換的配置:

Vue項目Webpack優化實踐,構建效率提高50%

項目中模塊熱替換的配置

7、提取公共代碼

如果每個頁面的代碼都將這些公共的部分包含進去,則會造成以下問題 :

• 相同的資源被重複加載,浪費用戶的流量和服務器的成本。

• 每個頁面需要加載的資源太大,導致網頁首屏加載緩慢,影響用戶體驗

如果將多個頁面的公共代碼抽離成單獨的文件,就能優化以上問題 。Webpack內置了專門用於提取多個Chunk中的公共部分的插件CommonsChunkPlugin。

項目中CommonsChunkPlugin的配置:

Vue項目Webpack優化實踐,構建效率提高50%

項目中CommonsChunkPlugin的配置

8、按需加載代碼

通過vue寫的單頁應用時,可能會有很多的路由引入。當打包構建的時候,javascript包會變得非常大,影響加載。如果我們能把不同路由對應的組件分割成不同的代碼塊,然後當路由被訪問的時候才加載對應的組件,這樣就更加高效了。這樣會大大提高首屏顯示的速度,但是可能其他的頁面的速度就會降下來。

項目中路由按需加載(懶加載)的配置:

Vue項目Webpack優化實踐,構建效率提高50%

項目中路由按需加載(懶加載)的配置

9、優化SourceMap

我們在項目進行打包後,會將開發中的多個文件代碼打包到一個文件中,並且經過壓縮,去掉多餘的空格,且babel編譯化後,最終會用於線上環境,那麼這樣處理後的代碼和源代碼會有很大的差別,當有bug的時候,我們只能定位到壓縮處理後的代碼位置,無法定位到開發環境中的代碼,對於開發不好調式,因此sourceMap出現了,它就是為了解決不好調式代碼問題的。

SourceMap的可選值如下:

Vue項目Webpack優化實踐,構建效率提高50%

SourceMap的可選值

開發環境推薦: cheap-module-eval-source-map

生產環境推薦: cheap-module-source-map

原因如下:

1. 源代碼中的列信息是沒有任何作用,因此我們打包後的文件不希望包含列相關信息,只有行信息能建立打包前後的依賴關係。因此不管是開發環境或生產環境,我們都希望添加cheap的基本類型來忽略打包前後的列信息。

2. 不管是開發環境還是正式環境,我們都希望能定位到bug的源代碼具體的位置,比如說某個vue文件報錯了,我們希望能定位到具體的vue文件,因此我們也需要module配置。

3. 我們需要生成map文件的形式,因此我們需要增加source-map屬性。

4. 我們介紹了eval打包代碼的時候,知道eval打包後的速度非常快,因為它不生成map文件,但是可以對eval組合使用 eval-source-map使用會將map文件以DataURL的形式存在打包後的js文件中。在正式環境中不要使用 eval-source-map, 因為它會增加文件的大小,但是在開發環境中,可以試用下,因為他們打包的速度很快。

10、構建結果輸出分析

Webpack輸出的代碼可讀性非常差而且文件非常大,讓我們非常頭疼。為了更簡單、直觀地分析輸出結果,社區中出現了許多可視化分析工具。這些工具以圖形的方式將結果更直觀地展示出來,讓我們快速瞭解問題所在。接下來講解vue項目中用到的分析工具:webpack-bundle-analyzer 。

項目中在webpack.prod.conf.js進行配置:

Vue項目Webpack優化實踐,構建效率提高50%

項目中在webpack.prod.conf.js進行配置

執行 $ npm run build --report 後生成分析報告如下:

Vue項目Webpack優化實踐,構建效率提高50%

作者:風逝123


分享到:


相關文章: