面試題:webpack之性能優化

移除插件某些包,減小插件體積

好比說通用的日期庫是moment.js,這個庫會佔用很大的體積,由於當引用這個庫的時候,全部的locale文件都被引入,而這些文件甚至在整個庫的體積中佔了大部分, 要想對此進行優化必須在webpack打包時移除這部份內容

webpack自帶的IgnorePlugin插件便會處理進行優化
javascript

plugins:[    
    new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/)
]複製代碼

以上配置忽略了時間格式化moment.js中的語言包
java

優化前node


優化後react



模塊化引入 按需導出

咱們在引入lodash這種重型的js庫的時候,咱們可能只須要引用裏面部分函數,可是當咱們所有引入打包lodash.js體積就會很龐大webpack

優化前es6


import _ from 'lodash';

console.log(_.map)
//ƒ map(collection,iteratee){var func=isArray(collection)?arrayMap:baseMap;return func(collection,getIteratee(iteratee,3));}複製代碼

可是咱們若是按需導入 這樣就會減小很大致積web

優化後json


import map from 'lodash/map';

console.log(map)
//ƒ map(collection, iteratee) {
  var func = isArray(collection) ? arrayMap : baseMap;
  return func(collection, baseIteratee(iteratee, 3));
}複製代碼


優化resolve.extensions配置 設置解析文件後綴

設置解析文件後綴,能夠加速文件尋找速度
resolve: {
    extensions: ['.js', '.json', 'jsx']
}複製代碼


優化resolve.modules配置

 resolve.modules 用於配置Webpack去哪些目錄下尋找第三方模塊。resolve.modules的默認值是[node modules],含義是先去當前目錄的/node modules目錄下去找咱們想找的模塊,若是沒找到,就去上一級目錄../node modules中找,再沒有就去../ .. /node modules中找,以此類推,這和Node.js的模塊尋找機制很類似。當安裝的第三方模塊都放在項目根目錄的./node modules目錄下時,就沒有必要按照默認的方式去一層層地尋找,能夠指明存放第三方模塊的絕對路徑,以減小尋找。  
resolve: {
    // 使用絕對路徑指明第三方模塊存放的位置,以減小搜索步驟
    modules: [path.resolve(__dirname,'node_modules')]
}複製代碼

優化loader配置 縮小文件搜索範圍

因爲Loader對文件的轉換操做很耗時,因此須要讓儘量少的文件被Loader處理。咱們能夠經過如下3方面優化Loader配置: 
(1)優化正則匹配 
(2)經過cacheDirectory選項開啓緩存 
(3)經過include、exclude來減小被處理的文件。 
module: {
    rules: [
        {
            test:/\.js$/,
            //babel-loader支持緩存轉換出的結果,經過cacheDirectory選項開啓
            loader:'babel-loader?cacheDirectory',
            //只對項目根目錄下的src 目錄中的文件採用 babel-loader
            include: [path.resolve('src')],
            //排除 node_modules 目錄下的文件,node_modules 目錄下的文件都是採用的 ES5 語法,不必再經過 Babel 去轉換
            exclude: path.resolve(__dirname, 'node_modules')
        }
    ]
}複製代碼

optimization.splitChunks 提取公共代碼

Webpack 4 移除了 CommonsChunkPlugin取而代之的是兩個新的配置項 optimization.splitChunks 和 optimization.runtimeChunk。
redux

CommonsChunkPlugin
緩存

webpack 將多個模塊打包以後的代碼集合稱爲 chunk。爲了將一些不多變化的經常使用庫(react、redux、lodash)與業務代碼分開,或者是一些不一樣入口共同使用的公共模塊,開發者經常須要將它們單獨打包,這些均可以經過配置 CommonsChunkPlugin 來實現。

entry: {
    app:'./main.js',
    vendor: ['react','react-dom']
},
plugins:
    new webpack.optimize.CommonsChunkPlugin({names:['vendor']})
]

複製代碼

webpack 4 準備經過 optimization.splitChunks 和 optimization.runtimeChunk 屬性來簡化代碼分割的配置

optimization.splitChunks

經過設置 optimization.splitChunks.chunks: "all" 來啓動默認的代碼分割配置項。  

當知足以下條件時,webpack 會自動打包 chunks: 

1)當前模塊是公共模塊(多處引用)或者模塊來自 node_modules 

2)當前模塊大小大於 30kb 若是此模塊是按需加載,並行請求的最大數量小於等於 5 

3)若是此模塊在初始頁面加載,並行請求的最大數量小於等於 3

optimization: {
    splitChunks: {
        chunks: 'all',
        name: true,
        automaticNameDelimiter: '-',  // 模塊間的鏈接符,默認爲"~"
        cacheGroups: {
            vendors: {
                test: /[\\/]node_modules[\\/]/,
                priority: -10  // 優先級,越小優先級越高
            },
            default: {  // 默認設置,可被重寫
                minChunks: 2,
                priority: -20,
                reuseExistingChunk: true  // 若是原本已經把代碼提取出來,則重用存在的而不是從新產生
            }
        }
    }
}複製代碼


用 Happypack 來加速代碼構建

因爲有大量文件須要解析和處理,構建是文件讀寫和計算密集型的操做,特別是當文件數量變多後,Webpack 構建慢的問題會顯得嚴重。 
運行在 Node.js 之上的 Webpack 是單線程模型的,也就是說 Webpack 須要處理的任務須要一件件挨着作,不能多個事情一塊兒作。 文件讀寫和計算操做是沒法避免的,那能不能讓 Webpack 同一時刻處理多個任務,HappyPack 就能讓 Webpack 作到這點,它把任務分解給多個子進程去併發的執行,子進程處理完後再把結果發送給主進程。
當同時讀取多個loader文件資源時,好比`babel-loader`須要 transform 各類jsx,es6的資源文件。在這種同步計算同時須要大量耗費 cpu 運算的過程當中,node的單進程模型就無優點了,而 Happypack 就是針對解決此類問題而生的存在
const HappyPack = require('happypack');
module: {    rules: [
        {
            test:/\.js/,
            //loader:'babel-loader',
            include: [path.resolve('src')],
            // 排除 node_modules 目錄下的文件,node_modules 目錄下的文件都是採用的 ES5 語法,不必再經過 Babel 去轉換
            exclude: path.resolve(__dirname, 'node_modules'),
            // 把對 .js 文件的處理轉交給 id 爲 babel 的 HappyPack 實例
            loader: 'happypack/loader?id=babel'
        }
    ]
},
plugins:[    new HappyPack({
        // 用惟一的標識符 id 來表明當前的 HappyPack 是用來處理一類特定的文件
        id: 'babel',
        // 如何處理 .js 文件,用法和 Loader 配置中同樣
        loaders: ['babel-loader?cacheDirectory'],
        // ... 其它配置項
    })
]

複製代碼

未完待續................

相關文章
相關標籤/搜索