1. 程式人生 > >webpack性能優化總結

webpack性能優化總結

單獨 set 基礎 common input echart clu 並且 from

一.縮小文件的搜索範圍

  1. 優化Loader配置
    使用配置項include與exclude盡可能高概率命中文件,減少webpack匹配文件的時間。
    我們可以適當的配置項目的結構目錄。
    module.exports = {
    module: {
        rules: [{
            test: /\.js?$/,
            include: path.resolve(__dirname, ‘app‘),
            use: {
              loader: ‘babel-loader?cacheDirectory‘,
              options: {
                presets: [‘es2015‘, ‘react‘, "stage-0"]
              }
            }
          }],
    },
    }

    技術分享圖片

  2. 優化resolve.modules
    指定模塊路徑,不需要按照默認的方式一層一層查找文件夾, 指定modules配置下的app目錄方便在引入其他組件可以以絕對路徑引入。引入方式如下截圖:
    module.exports = {
    resolve: {
    extensions: [‘.js‘, ‘.jsx‘],
    modules: [
    path.resolve(dirname, ‘app‘),
    path.resolve(
    dirname, ‘node_modules‘)
    ]
    }
    }
    技術分享圖片
    ReactEcharts是npm安裝的模塊,Input是自己寫在公共組件components的文件夾,由於components在app文件夾下
    根據配置,可以直接以此種方式引入。
  3. 優化resolve.extensions
    此配置項默認配置為:
    extensions: [‘js‘, ‘json‘]
    如果這個數組列表越長, 或者正確的後綴越往後, 就會造成嘗試的次數越多,所以resolve.extensions盡量減少後綴嘗試的可能性。建立配置為:
    extensions: [‘js‘],

二. 使用DLLPLUGIN
為什麽web項目構建介入動態連接庫的思想後,會大大提升構建速度呢?原因在於,包含大量復用模塊的動態鏈接庫只需被編譯一次,在之後的構建過程中被動態鏈接庫包含的模塊將不會被重新編譯,而是直接使用動態連接庫中的代碼。要給web項目構建接入動態鏈接庫的思想,需要完成以下事情。

  • 將網頁依賴的基礎模塊抽離出來,打包成一個個單獨的動態鏈接庫中。在一個動態鏈接庫中可以包含多個模塊。
  • 當需要導入的模塊存在於某個動態鏈接庫,這個模塊不能再次打包,而是去動態鏈接庫中去獲取。
  • 頁面依賴的所有動態鏈接庫都需要被加載。
    下面以react項目為例。
    webpack已經內置了對動態鏈接庫的插件Dllplugin以及DllReferencePlugin
    首先看構建成功之後的目錄結構
    技術分享圖片
    以及構建webpack的配置,下圖是webpack_dll.config.js文件:
    技術分享圖片
    下圖是webpack配置主文件的重要配置:
    技術分享圖片
    編譯主webpack文件,自動加入dll.js以及main.js
    下圖是頁面引入dll依賴以及引入主js:
    技術分享圖片
    接下來講解如何實現。
    webpack_dll.config.js負責構建dll.js,在項目中把react的基本依賴庫打包成react.dll.js,
    把常用的polyfill打包成polyfill.dll.js。這兩個需要在index.html引入。在webpack主配置中利用DllReferencePlugin插件根據對應名字的json文件,json文件會根據id與路徑,引入打包好的dll文件。並且在main.js中不會出現dll重復打包的模塊(react等配置進去的模塊不會再次打包如main.js),減少主要js的體積,提高構建速度。
    執行構建時,首先要編譯webpack_Dll.config.js,構建出配置的dll,然後再編譯webpack的主配置,編譯出main.js,然後引入dll系列js,最後引入main.js。
    由於動態鏈接庫大多數包含的是常用的第三方庫,一般都不會隨意升級,在package.json的依賴上刪除^標示。當涉及dll的庫升級,或者添加第三方庫,就需要重新編譯了。

三. 使用HappyPack
HappyPack 是通過把loader交給程序多進程去並發處理,由於js是單線程,只能通過多進程去發揮cpu的功能。配置也相對簡單。
技術分享圖片
技術分享圖片
四. 使用Tree Shaking
TreeShaking可以用來提出JavaScript中用不上的死代碼.它依賴靜態的ES6模塊化語法。Webpack2.0版本經已內置。從一簡單例子解釋Tree Shaking的作用。假如有一個文件util.js裏存有兩函數。在main.js引入和使用util.js
util.js源碼如下
export function funcA(){<br/>}<br/>export function funcB() {<br/>}<br/>
main.js源碼如下
import { funcA } from ‘./util.js‘ funcA()
經過TreeShaking後 util中funcB函數沒有被引入使用就會被TreeShaking當作死代碼剔除。
接下來講解如何配置Webpack讓Tree Shaking,以react項目為例子。
首先修改babel的規則
presets: [["env, { modules: false }"], ‘react‘, ‘statge-0‘]
其中modules: false的含義是關閉Babel的模塊轉換功能,保留原本的ES6模塊化語句。
修改第三方庫的引入文件規則
以redux為例子,其發布到Npm上的目錄結構為:
|-- es
---- index.js
|-- lib
---- index.js
package.json
在package.json有兩個字段
"main": "lib/index.js", // 采用commonJs模塊化入口
"jsnext:main": "es/index.js", // 采用es6模塊化入口
以下配置的含義優先使用jsnext:main作為入口,即采用es6模塊化入口代碼。
modules.exports = {
resolve: {
mainFields: [‘jsnext:main‘, ‘browser‘, ‘main‘],
},
}
然後配合UglifyJS插件處理一遍代碼,即可剔除死代碼,提高構建速度。
技術分享圖片
如出現當前問題只需npm install babel-preset-env -D安裝babel-preset-env依賴即可。
五.使用ParalleUglifyPlugin
ParalleUglifyPlugin采用多進程壓縮代碼,每個進程還是通過UglifyPlugin去壓縮代碼。
技術分享圖片
更多參數配置詳見https://www.npmjs.com/package/webpack-parallel-uglify-plugin

webpack性能優化總結