webpack性能優(yōu)化分析

1. 優(yōu)化原理和目標

診斷并分析性能瓶頸,有針對性的提升構(gòu)建速度和用戶的訪問性能

診斷方法:

  • 構(gòu)建速度:提升團隊開發(fā)效率

  • 構(gòu)建體積:提升頁面訪問速度

優(yōu)化方案:

  • 使用多線程優(yōu)化構(gòu)建速度

  • 使用分包減少構(gòu)建體積

  • 減少構(gòu)建目標提升構(gòu)建速度

2. 分析構(gòu)建速度-測量插件 speed-measure-webpack-plugin

https://github.com/stephencookdev/speed-measure-webpack-plugin

介紹:

顯示每個loader和plugin的執(zhí)行時間,將比較耗時的用紅色標記出來

安裝:

npm install speed-measure-webpack-plugin -D

使用:

const SpeedMeasurePlugin = require("speed-measure-webpack-plugin");
const smp = new SpeedMeasurePlugin();
const webpackConfig = smp.wrap({
    plugins: [new MyPlugin(), new MyOtherPlugin()],
});

3. 構(gòu)建體積檢測插件 webpack-bundle-analyzer

https://github.com/webpack-contrib/webpack-bundle-analyzer

介紹:

webpack-bundle-analyzer是webpack的插件,需要配合webpack和webpack-cli?起使?。這個插件可以讀取output?件夾中的stats.json?件,把該?件可視化展現(xiàn),?成代碼分析報告,可以直觀地分析打包出的?件有哪些,及它們的??、占?情況、各?件 Gzipped 后的??、模塊包含關(guān)系、依賴項等。

安裝:

npm install --save-dev webpack-bundle-analyzer

使用:

const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
module.exports = {
    plugins: [new BundleAnalyzerPlugin()]
}

通過分析圖可以幫助我們:

  • 了解bundle包中真正的內(nèi)容

  • 找出哪些模塊尺寸最大

  • 查找誤引入的模塊

  • 優(yōu)化項目

4. 構(gòu)建性能優(yōu)化之多進程 thread-loader

4.1 多進程 thread-loader

https://github.com/webpack-contrib/thread-loader

介紹:

Webpack的構(gòu)建過程涉及到?量的?件讀寫操作,系統(tǒng)的I/O操作是?分耗時的,當要操作的?件數(shù)量變多的時候,Webpack的構(gòu)建速度也會相應的變慢。由于JavaScript是單線程運?的,只能?個?個的排隊處理任務,不能同時處理多個任務。像Java那樣使?多線程進?任務處理顯然是不可能的,因此thread-loader使?多進程來并發(fā)去處理任務,?進程處理完成后將結(jié)果再返回給主進程,從?提升了構(gòu)建效率。

注意:
  • thread-loader應該放到其他loader前

  • 每個 worker 都是?個獨?的 node.js 進程,其開銷?約為 600ms 左右。同時會限制跨進程的數(shù)據(jù)交換。

  • 請僅在耗時的操作中使?此 loader

運行在worker池中的loader的限制:
  • 不能生成新的文件

  • 不能使用自定義的loader API (也就是說,不能通過插件來自定義)

  • 無法獲取webpack的配置

安裝:

npm install --save-dev thread-loader

使用:

module.exports = {
    module: {
        rules: [
            {
                test: /\.js$/,
                include: path.resolve('src'),
                use: [
                        'thread-loader',
                        // your expensive loader (e.g babel-loader)
                     ],
                   },
               ],
           },
 };

4.2 多進程-并行壓縮- tenser-webpack-plugin

https://github.com/webpack-contrib/terser-webpack-plugin

使用:開啟parallel參數(shù)

5. 分包和模板的自動引用

分包:在 webpack 打包過程中,經(jīng)常出現(xiàn) vendor.js, app.js 單個?件較?的情況,這偏偏?是??最先加載的?件,這就會使得加載時間過?,從?使得?屏時間過?,影響?戶體驗。因此我們需要將打包?件進?步優(yōu)化 - 分包。把變化?率很?的第三?庫抽離出來,提前打包好,使?DllPlugin進?分包。

分包原則:
  • 降低單個包的文件大小

  • 將第三方庫分離出來

實現(xiàn)步驟:
  • 分包:定義webpack.dll.js,使用DllPlugin配置分包
const path = require('path')
const webpack = require('webpack')

module.exports = {
  mode: 'production',
  entry: {
    react: [
      'react',
      'react-dom'
    ]
  },
  output: {
    filename: '[name].dll.js',
    path: path.join(__dirname, 'dll'),
    library: '[name]_[hash]'
  },
  plugins: [
    new webpack.DllPlugin({
      name: '[name]_[hash]',
      path: path.join(__dirname, 'dll/[name]-manifest.json'),
    })
  ]
}
  • 排除分包:在config中,使用DllReferencePlugin引用manifest文件排除分包
plugins: [
    new webpack.DllReferencePlugin({
      context: __dirname,
      manifest: path.resolve(__dirname, './dll/react-manifest.json')
    }),
  ]
  • 引用dll:使用add-asset-html-webpack-plugin引用分包文件

https://github.com/SimenB/add-asset-html-webpack-plugin

注意:

SpeedMeasurePlugin和AddAssetHtmlPlugin一起使用,會導致dll.js文件自動導入失敗,所以,在使用AddAssetHtmlPlugin的時候,將SpeedMeasurePlugin的disable改為true

new AddAssetHtmlPlugin({
  filepath: path.resolve(__dirname, './dll/react.dll.js'),
  publicPath: '', // 否則在html中引入的的路徑會有一個auto
})

6. 使用緩存提升打包性能

https://webpack.docschina.org/configuration/cache/#root

目的: 提升二次構(gòu)建速度

思路:

  • babel-loader 開啟緩存

  • 設置cache選項

6.1 babel-loader 開啟緩存

  {
      loader: 'babel-loader',
        options: {
          cacheDirectory: true
        }
      }
  }

6.2 設置cache選項

cache: {
    type: 'filesystem',
    allowCollectingMemory: true,
  },

7. 縮小構(gòu)建目標

目的:縮小構(gòu)建目標 (比如 babel-loader 不解析 node_modules)

7.1 babel-loader 只解析src

  {
        test: /.js$/,
        include: path.resolve('src'),
        use: [
          {
            loader: 'thread-loader',
            options: {
              workers: 3,
            }
          },
          {
            loader: 'babel-loader',
            options: {
              cacheDirectory: true
            }
          }
        ]
      }, 

7.2 修改resolve的參數(shù)

resolve: {
    alias: {
      'react': path.resolve(__dirname, './node_modules/react/umd/react.production.min.js'),
      'react-dom': path.resolve(__dirname, './node_modules/react-dom/umd/react-dom.production.min.js')
    },
    extensions: ['.js'],
    mainFields: ['main']
  }

8. 圖片壓縮 image-minimizer-webpack-loader

https://github.com/webpack-contrib/image-minimizer-webpack-plugin/

9. CSS優(yōu)化 purgecss-webpack-plugin

https://github.com/FullHuman/purgecss/tree/main/packages/purgecss-webpack-plugin

介紹:

在?型項?中,經(jīng)常會有很多樣式內(nèi)容,在代碼中根本未使?,但是會被打包,這些樣式在打包時應該 移除。 使?purgecss-webpack-plugin移除未使?的css樣式

使用:

const { PurgeCSSPlugin } = require("purgecss-webpack-plugin")
const PATHS = {
  src: path.join(__dirname, "src"),
}
plugins: [
    new PurgeCSSPlugin({
      paths: glob.sync(`${PATHS.src}/**/*`, { nodir: true }),
    })
]

注意:purgecss-webpack-plugin需要和mini-css-extract-plugin一起使用

10. 使用高版本的webpack和node.js

更高版本的webpack和nodejs,性能更加優(yōu)越

上述是針對webpack5的性能優(yōu)化分析,如有錯誤之處,請指正~

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容