webpack打包优化
工具
-
利用webpack-bundle-analyzer插件查看打包尺寸
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; module.exports = { // ... plugins: [ new BundleAnalyzerPlugin() ] };
运行打包命令就会在浏览器中打开生成的报告,可以看到一个可视化的分析界面,显示了各个模块的大小、依赖关系等信息。通常情况下,报告会在默认端口(8888)上启动一个本地服务器,你只需要在浏览器中访问 http://localhost:8888 即可查看报告
通过这个插件我们可以查看项目里比较大的模块信息,针对性优化 -
利用speed-measure-webpack-plugin插件查看打包的时间
const SpeedMeasurePlugin = require('speed-measure-webpack-plugin'); const smp = new SpeedMeasurePlugin(); module.exports = smp.wrap({ // ... 原始的 webpack 配置 });
打包之后你会获得类似以下的结果
SMP ⏱ 25.123s Hash: abcdef123456 Version: webpack 4.46.0 Time: 25123ms Built at: 2024-03-11 15:00:00 Asset Size Chunks Chunk Names main.js 1.23 MiB 0 [emitted] [big] main ... Entrypoint main = main.js ... Performance Asset Size Chunks Chunk Names main.123456.js 1.23 MiB 0 [emitted] main ... Entrypoint main = main.123456.js ... Loaders: babel-loader (1234ms) css-loader (2345ms) less-loader (3456ms) ... Modules (top 10): ./src/index.js (1234ms) ./src/components/Button/Button.js (2345ms) ./node_modules/react/react.js (3456ms) ... Build completed in 25.123 seconds.
它分析 webpack 的总打包耗时以及每个 plugin 和 loader 的打包耗时,从而让我们对打包时间较长的部分进行针对性优化
措施
-
代码分割(Code Splitting)提取公共模块比如react|react-dom
// webpack.config.js module.exports = { optimization: { splitChunks: { chunks: 'all', minSize: 20000, minChunks: 1, maxAsyncRequests: 5, maxInitialRequests: 3, automaticNameDelimiter: '~', cacheGroups: { vendor: { test: /[\\/]node_modules[\\/](react|react-dom)[\\/]/, name: 'vendors', priority: -10, chunks: 'all' }, default: { minChunks: 2, priority: -20, reuseExistingChunk: true } } } } };
-
代码压缩,js生成环境会自动压缩,以下是css 和图片的
css// webpack.config.js const MiniCssExtractPlugin = require('mini-css-extract-plugin'); module.exports = { module: { rules: [ { test: /\.css$/, use: [MiniCssExtractPlugin.loader, 'css-loader'] } ] }, plugins: [ new MiniCssExtractPlugin() ] };
图片压缩与转换
// webpack.config.js module.exports = { module: { rules: [ { test: /\.(png|jpe?g|gif)$/, use: [ { loader: 'url-loader', options: { limit: 8192, // 小于 8KB 的图片会转成 base64 格式 name: 'images/[name].[hash:8].[ext]' } } ] } ] } };
-
针对静态资源文件,可以使用 webpack-cdn-plugin 等插件将其引入 CDN,加快资源加载速度
const WebpackCdnPlugin = require('webpack-cdn-plugin'); module.exports = { plugins: [ new WebpackCdnPlugin({ modules: [ { name: 'react', var: 'React', path: 'umd/react.production.min.js' }, { name: 'react-dom', var: 'ReactDOM', path: 'umd/react-dom.production.min.js' } ], publicPath: '/node_modules' }) ] };
-
编译缓存
// webpack.config.js module.exports = { module: { rules: [ { test: /\.js$/, use: ['cache-loader', 'babel-loader'] } ] } };
-使用thread-loader 可以将一些耗时的 loader 操作移至 worker pool 中并行处理,从而提升构建速度
module.exports = { // other configurations module: { rules: [ { test: /\.js$/, use: [ 'thread-loader', // 其他 loader 'babel-loader', ], }, ], }, };
docker构建镜像时采用分层构建
- docker采用分层构建减小镜像的体积 示例
# 第一阶段:构建前端应用 FROM node:latest as compile WORKDIR /usr/src/app/ COPY package.json ./ RUN npm i --registry=https://registry.npm.taobao.org COPY . . RUN npm run build # 第二阶段:运行应用 FROM nginx COPY ./docker/nginx.conf /etc/nginx/conf.d/default.conf COPY --from=compile /usr/src/app/build /usr/share/nginx/html/ EXPOSE 8080 CMD ["nginx", "-g", "daemon off;"]