如何讓老項目的打包構建時間減小70%?

希沃ENOW大前端javascript

公司官網:CVTE(廣州視源股份)css

團隊:CVTE旗下將來教育希沃軟件平臺中心enow團隊前端

本文做者:java

小羽名片.png

Hello,你們好,我是小羽同窗,一個平凡而又不甘於平凡的前端開發工程師。react

今天的話,主要是想和你們聊聊小羽是怎麼把一個react老項目構建時間減小70%+的。webpack

小羽最近接手了一個3年前的老項目web

看了下版本,react 16.0 + ts + webpack4,感受還行shell

可是據說中間有接近一年的時間沒人維護,本來熟悉項目的人都溜了。npm

image-20210621194704744-4276028.png

還沒來的及詳細研究代碼,需求就到了。babel

只能硬着頭皮上了,還好有個人導師兵哥從旁協助。

前期的開發也算是有驚無險的渡過了吧。

最近幾天剛開發完一個版本,而後發現咱們項目的構建時間實在過久了

XDM,若是我說打包一個react項目竟然要150s,大家敢相信嗎?

小羽當時也是懵了

147s,這但是2分半的時間。。。

image-20210621194742994-4276065.png

image-20210619103016762.png

image-20210619101825200.png

看了一下cpu的利用率,平均下來大概就是20%左右。這個利用率也過低了吧?徹底沒有把cpu的性能發揮出來。

happypack

而後小羽找了下webpack打包優化相關的包。而後發現了網上大多數都是說happypack這個插件能夠進行多線程的優化。

那就整起唄。

image-20210621194852686-4276134.png

npm install happypack --save-dev
複製代碼

配置大概以下

const HappyPack = require('happypack');
const happyThreadPool = HappyPack.ThreadPool({size: require('os').cpus().length})

module.exports = {
    ...
    module: {
        rules: [
            test: /\.js$/,
            use: ['happypack/loader?id=js'],
        ],
        plugins: [
          ...,
          new HappyPack({
              id: 'js',
              loaders: ['babel-loader'],
  						threadPool: happyThreadPool,
          })
      ]
    }
}
複製代碼

運行了一下

嗯,還不錯,單js的轉譯就減小了20s

thread-loader

然而,小羽在css/less打包優化的時候遇到了問題。

緣由是css/less中用到了mini-css-extract-plugin這個樣式抽離插件,刪除這個插件後打包又是正常的。

查閱npm中的文檔,發現做者因爲對改項目的興趣消退,在兩年前已經斷更了。。。

而後做者給咱們推薦了thread-loader,那就轉到thread-loader中去看看吧。

image-20210621164930138.png

thread-loader中提到,thread-loader中是沒法使用自定義加載器 API(即經過插件)。

而loader的加載順序是從右往左從下往上加載的。

像下面這個loader的加載順序則是less-loader => css-loader => style-loader

{
  	test: /\.less$/,
    use: [
      'style-loader',
      'css-loader', 
      'less-loader'
    ],
},
複製代碼

那麼問題解決,只要咱們在引用mini-css-extract-plugin前加載thread-loader就不會報錯了。

完成全部的配置後,我們再來嘗試一下。

添加了thread-loader的優化後打包構建的時間大概來到了120s左右,和未優化前相比,減小了25-30s

image-20210621162853154.png

而後cpu的利用率也終於起來了,在loader編譯階段,利用率能夠提高到40%多。

image-20210621162647423.png

terser-webpack-plugin

但是120s的時間仍是很長,這時候怎麼處理呢?

其實在webpack的打包構建中耗時較多的兩個步驟應該是loader的轉譯以及代碼的混淆壓縮。(前提是得有這兩個)

轉譯已經搞定了,那我們處理混淆壓縮吧。

看了下項目,發現用的是uglifyjs-webpack-plugin這個插件進行混淆壓縮。

那就看下官網吧

嗯,你肯定沒有在逗我嗎?又是兩年前斷更了,這。。。

image-20210621164838233.png

我不想優化了!!!

都是些啥玩意啊!!!

image-20210621195043046.png

哈哈哈,開個玩笑

優化那是必須得繼續的。那就只可以繼續查閱資料啦。

一個偶然的機會,發現了我們接下來的主角——terser-webpack-plugin

記住,若是是webpack4的版本那麼也要安裝terser-webpack-plugin v4的版本。v5的版本是給webpack5來使用的。

image-20210621170220107.png

小羽這邊接受的項目是webpack4,那就用v4的,而後看了下插件的版本。v4最新的是4.2.3

npm install terser-webpack-plugin@4.2.3 --save-dev
複製代碼
const TerserPlugin = require('terser-webpack-plugin');
module.exports = {
	...
	optimization:{
    minimizer: [
      new TerserPlugin({
        parallel: require('os').cpus().length - 1,
        terserOptions:{
          compress:{
            inline:false
          },
          mangle: {
            safari10: true
          }
        }
      })
    ]
  }
}
複製代碼

parallel參數是用來設置你啓動的線程數的。

require('os').cpus().length - 1,表明獲取你電腦全部線程-1的數量。

而後這裏得提一下,並非啓動的線程數量越多就越好的(包括前面的thread-loader)。

由於咱們每啓動一個線程都是須要消耗必定的時間的,這個時間約爲600ms

舉個🌰,假如如今你用的是一臺8核16線程的電腦。我們把全部的線程都啓動起來,那麼啓動的時間約爲9.6s

可是當我們的項目比較小,本來打包的時間可能就五、6s,壓縮的時間可能連600ms都不到,這樣的話我們的打包優化就變成了負優化了。

因此並非每個項目都須要開啓多線程的。是否要開啓?開啓多少個線程?這些都是須要看狀況的。

terser-webpack-pluginterserOptions參數基本與uglifyjs-webpack-plugin的uglifyOptions是一致的,直接平滑升級,美滋滋~

那我們來測試一下吧~

構建時間約爲41s,nice~

image-20210621174356550.png

而後在看一下我們混淆壓縮時候的cpu負載也是彪了上來,cpu負載最高可到92%

image-20210621173705668.png

最後我們計算一下

未優化前147s,優化後41s,一共減小了106s,減小了快兩分鐘的時間。

那我們在計算一下提高的性能,(147-41)/147≈0.72。提高了72%

image-20210621195143493.png

小結

小羽在本文中和小夥伴們聊了下在工做中是如何優化一個老項目的webpack打包構建經歷,向小夥伴們介紹了happypackthread-loader以及terser-webpack-plugin的用法。但願可以給小夥伴們在webpack的構建中帶來一些幫助,也但願小夥伴們能夠從中獲得一些啓發~

相關文章
相關標籤/搜索