本文將從打包分析,速度優化,體積優化三個方面進行闡述javascript
打包分析css
初級分析: webpack內置的stats(構建的統計信息)html
webpack --config webpack.prod.js --json > stats.json
速度分析:speed-measure-webpack-plugin(分析整個打包總耗時&每一個插件和loader的耗時狀況)html5
const SpeedMeasurePlugin = require("speed-measure-webpack-plugin");
const smp = new SpeedMeasurePlugin();
const webpackConfig = smp.wrap({ plugins: [ new MyPlugin(), new MyOtherPlugin() ] })
體積分析: webpack-bundle-analyzer分析依賴的第三方模塊文件和業務裏面的組件代碼大小java
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
module.exports = { plugins: [ new BundleAnalyzerPlugin() ] }
速度優化node
使用高版本的webpack react
多進程構建webpack
happypack:每次 webapck 解析一個模塊,HappyPack 會將它及它的依賴分配給 worker 線程中web
exports.plugins = [ new HappyPack({ id: 'jsx', threads: 4, loaders: [ 'babel-loader' ] }), new HappyPack({ id: 'styles', threads: 2, loaders: [ 'style-loader', 'css-loader', 'less-loader' ] })];
exports.module.rules = [ { test: /\.js$/, use: 'happypack/loader?id=jsx' }, { test: /\.less$/, use: 'happypack/loader?id=styles' } ]
thread-loader:每次 webpack 解析一個模塊,thread- loader 會將它及它的依賴分配給 worker 線程中json
module.exports = { module: { rules: [ { test: /\.js$/, include: path.resolve("src"), use: [ { loader: "thread-loader" options: { workers: 2 // worker的數量,默認是cpu核心數 } } } ] }}
多進程並行壓縮代碼
const TerserPlugin = require('terser-webpack-plugin');
module.exports = { optimization: { minimize: true, minimizer: [ new TerserPlugin({ parallel: true }) ] }}
預編譯資源模塊
webpack.dll.config.js文件:
const path = require('path');const webpack = require('webpack');
module.exports = { context: process.cwd, resolve: { extensions: ['.js', '.jsx', '.json', '.styl', '.css'], modules: [__dirname, 'node_modules'] }, entry: { vendor: [ 'react', 'react-dom', 'react-router-dom' ] }, output: { path: path.resolve(__dirname, './dist/lib'), filename: '[name].js', library: '[name]' }, plugins: [ new webpack.DllPlugin({ path: path.resolve(__dirname, '.', '[name]-manifest.json'), name: '[name]' }) ]};
運行
webpack --config webpack.dll.config.js --mode production
生成vendor-manifest.json文件
webpack.config.js文件:
module.exports = { plugins: [ new webpack.DllReferencePlugin({ manifest: require('./vendor-manifest.json') }) ]}
html:
<script type="text/javascript" src="./lib/vendor.js"></script>
基礎庫分離
經過html-webpack-externals-plugin,而後在html裏面直接引入組件庫的cdn連接
const HtmlWebpackExternalsPlugin = require('html-webpack-externals-plugin')
moudles.export = { plugins: [ new HtmlWebpackExternalsPlugin({ externals: [ { module: 'react', entry: '//11.url.cn/now/lib/16.2.0/react.min.js', global: 'React' }, { module: 'react-dom', entry: '//11.url.cn/now/lib/16.2.0/react-dom.min.js', global: 'ReactDom' } ] }) ]}
html:
<script type="text/javascript" src="https://11.url.cn/now/lib/16.2.0/react.min.js"></script><script type="text/javascript" src="https://11.url.cn/now/lib/16.2.0/react-dom.min.js"></script>
經過webpack4的SplitChunksPlugins(webpack3使用的是commonChunksPlugin)
module.exports = {plugins: [new HtmlWebpackPlugin({template: path.join(__dirname, "./src/pages/search/search.html"),filename: "search.html",chunks: ["vendors", "common", "search"],inject: true,minify: {html5: true,collapseWhitespace: true,preserveLineBreaks: false,minifyCSS: true,minifyJS: true,removeComments: false}})],optimization: {splitChunks: {minSize: 0,cacheGroups: {vendors: {test: /(react|react-dom)/,name: "vendors",chunks: "all",priority: -10},common: {name: "commons",chunks: "all",minChunks: 2,priority: -20}}}}}
利用緩存:第一次構建花費正常的時間,第二次構建速度將顯著加快、
babel-loader開啓緩存
module: { rules: [ { test: /\.js$/, exclude: 'node_modules', use: { loader: 'babel-loader', options: { cacheDirectory: true } } } ]}
erser-webpack-plugin:開啓緩存
module.exports = { optimization: { minimize: true, minimizer: [ new TerserPlugin({ cache: true }) ] }}
使用 cache-loader 或者 hard-source-webpack-plugin
module.exports = { module: { rules: [ { test: /\.js$/, use: [ 'cache-loader', 'babel-loader' ], include: path.resolve('src') } ] }}
縮小構建目標
babel-loader不解析node-modules
exclude: "node-modules"
減小文件搜索範圍
module: { resolve: { alias: { react: path.resolve(__dirname, "./node_modules/react/dist/react.min.js") }, modules: [path.resolve(__dirname, "node_modules")], extensions: [".js"], mainFields: ["main"] } }
體積優化
Scope Hoisting
webpack4 mode 爲 production 默認開啓
plugins:
new webpack.optimize.ModuleConcatenationPlugin()
使用Tree shaking擦除無用的javaScript和css
概念:1個模塊可能有多個方法,只要其中的某個方法使用到了,則整個文件都會被打到 bundle ⾥去,tree shaking 就是隻把用到的方法打⼊ bundle ,沒⽤到的方法會在 uglify 階段被擦除掉。
使⽤:webpack production mode的狀況下默認開啓
要求: 必須是 ES6 的語法,CJS的方式不支持
CSS:purgecss-webpack-plugin 和 mini-css-extract-plugin 配合使用
圖片壓縮
loader: "image-webpack-loader"
使用動態polyfill-service或者browserlist