webpack 打包优化的四种方法(多进程打包,多进程压缩,资源 CDN,动态 polyfill)
2019-11-16 20:46
1361 查看
如今,
webpack毫无疑问是前端构建领域里最耀眼的一颗星,无论你前端走哪条路线,都需要有很强的
webpack知识。
webpack的基本用法这里就不展开讲了。主要探讨一下如何提高
webpack的打包速度。
这篇文章以
vue cli3.0+,webpack4.0+,nodejs10.0+这几个版本为例。
一、打包分析
1.1、速度分析
我们的目的是优化打包速度,那肯定需要一个速度分析插件,此时
speed-measure-webpack-plugin就派上用场了。它的作用如下:
- 分析整个打包总耗时
- 每个
plugin
和loader
的耗时情况
首先,安装插件
npm i -D speed-measure-webpack-plugin
然后修改
vue.config.js配置文件 (
vuecli3+版本的配置文件统一在这个文件里修改,如果没有该文件,在根目录新建一个)
// 导入速度分析插件 const SpeedMeasurePlugin = require("speed-measure-webpack-plugin"); // 实例化插件 const smp = new SpeedMeasurePlugin(); module.exports = { configureWebpack: smp.wrap({ plugins: [ // 这里是自己项目里需要使用到的其他插件 new yourOtherPlugin() ] }) }
运行打包命令之后,可以看到,打包总耗时为
2min,51.99s
1.2、体积分析
分析完打包速度之后,接着我们来分析打包之后每个文件以及每个模块对应的体积大小。使用到的插件为
webpack-bundle-analyzer,构建完成后会在
8888端口展示大小。
首先,安装插件
npm i -D webpack-bundle-analyzer
修改
vue.config.js配置文件
// 导入速度分析插件 const SpeedMeasurePlugin = require("speed-measure-webpack-plugin"); // 导入体积分析插件 const BundleAnalyzerPlugin = require("webpack-bundle-analyzer").BundleAnalyzerPlugin; // 实例化速度分析插件 const smp = new SpeedMeasurePlugin(); module.exports = { configureWebpack: smp.wrap({ plugins: [ // 实例化体积分析插件 new BundleAnalyzerPlugin() ] }) }
构建之后可以看到,其中黄色块
chunk-vendors文件占比最大,为
1.34MB
二、打包优化
2.1、多进程多实例构建,资源并行解析
多进程构建的方案比较知名的有以下三个:
- thread-loader (推荐使用这个)
- parallel-webpack
- HappyPack
这里以
thread-loader为例配置多进程多实例构建
安装
loader
npm i -D thread-loader
接下来在
vue.config.js配置文件中使用该
loader
// 导入速度分析插件 const SpeedMeasurePlugin = require("speed-measure-webpack-plugin"); // 实例化插件 const smp = new SpeedMeasurePlugin(); module.exports = { configureWebpack: smp.wrap({ module: { rules: [ { test: /\.js$/, use: ['thread-loader'] } ] } }) }
然后看下构建花费的时间,
2min,49.21s,相较于之前提升了
5s
2.2、公用代码提取,使用 CDN 加载
对于vue,vuex,vue-router,axios,echarts,swiper等我们可以利用webpack的externals参数来配置,这里我们设定只需要在生产环境中才需要使用。
下面配置
vue.config.js
// 导入速度分析插件 const SpeedMeasurePlugin = require("speed-measure-webpack-plugin"); // 导入体积分析插件 const BundleAnalyzerPlugin = require("webpack-bundle-analyzer").BundleAnalyzerPlugin; //判断是否为生产环境 const isProduction = process.env.NODE_ENV === 'production'; //定义 CDN 路径,这里采用 bootstrap 的 cdn const cdn = { css: [ 'https://cdn.bootcss.com/Swiper/4.5.1/css/swiper.min.css' ], js: [ 'https://cdn.bootcss.com/vue/2.6.10/vue.min.js', 'https://cdn.bootcss.com/vue-router/3.1.3/vue-router.min.js', 'https://cdn.bootcss.com/vuex/3.1.1/vuex.min.js', 'https://cdn.bootcss.com/axios/0.19.0/axios.min.js', 'https://cdn.bootcss.com/echarts/4.3.0/echarts.min.js', 'https://cdn.bootcss.com/Swiper/4.5.1/js/swiper.min.js', ] } // 实例化插件 const smp = new SpeedMeasurePlugin(); module.exports = { chainWebpack: config => { // 生产环境配置 if (isProduction) { // 生产环境注入 cdn config.plugin('html') .tap(args => { args[0].cdn = cdn; return args; }); } }, configureWebpack: smp.wrap({ module: { rules: [ { test: /\.js$/, use: ['thread-loader'] } ] }, plugins: [ new BundleAnalyzerPlugin() ], //生产环境注入 cdn externals: isProduction && { 'vue': 'Vue', 'vuex': 'Vuex', 'vue-router': 'VueRouter', 'axios': 'axios', 'echarts': 'echarts', 'swiper': 'Swiper' } || {} }) }
紧接着,改造
html页面。用于让我们配置的
cdn路径注入到
html页面
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width,initial-scale=1.0"> <!-- 使用 CDN 的 CSS 文件 --> <% for (var i in htmlWebpackPlugin.options.cdn && htmlWebpackPlugin.options.cdn.css) { %> <link href="<%= htmlWebpackPlugin.options.cdn.css[i] %>" rel="stylesheet"> <% } %> </head> <body> <noscript> <strong>We're sorry but eye-admin doesn't work properly without JavaScript enabled. Please enable it to continue.</strong> </noscript> <div id="app"></div> <!-- built files will be auto injected --> <!-- 使用 CDN 的 JS 文件 --> <% for (var i in htmlWebpackPlugin.options.cdn && htmlWebpackPlugin.options.cdn.js) { %> <script src="<%= htmlWebpackPlugin.options.cdn.js[i] %>"></script> <% } %> </body> </html>
最重要的一步,看下效果,可以看到现在耗时
1min,39.19s,整整提升了 1 分多钟!
2.3、多进程多实例并行压缩
并行压缩主流有以下三种方案
- 使用 parallel-uglify-plugin 插件
- uglifyjs-webpack-plugin 开启 parallel 参数
- terser-webpack-plugin 开启 parallel 参数 (推荐使用这个,支持 ES6 语法压缩)
安装插件依赖
npm i -D terser-webpack-plugin
接下来在
vue.config.js配置文件中使用插件,最终的配置文件如下
// 导入速度分析插件 const SpeedMeasurePlugin = require("speed-measure-webpack-plugin"); // 导入代码压缩插件 const TerserPlugin = require("terser-webpack-plugin"); // 导入体积分析插件 const BundleAnalyzerPlugin = require("webpack-bundle-analyzer").BundleAnalyzerPlugin; //判断是否为生产环境 const isProduction = process.env.NODE_ENV === 'production'; //定义 CDN 路径,这里采用 bootstrap 的 cdn const cdn = { css: [ 'https://cdn.bootcss.com/Swiper/4.5.1/css/swiper.min.css' ], js: [ 'https://cdn.bootcss.com/vue/2.6.10/vue.min.js', 'https://cdn.bootcss.com/vue-router/3.1.3/vue-router.min.js', 'https://cdn.bootcss.com/vuex/3.1.1/vuex.min.js', 'https://cdn.bootcss.com/axios/0.19.0/axios.min.js', 'https://cdn.bootcss.com/echarts/4.3.0/echarts.min.js', 'https://cdn.bootcss.com/Swiper/4.5.1/js/swiper.min.js', ] } // 实例化插件 const smp = new SpeedMeasurePlugin(); module.exports = { chainWebpack: config => { // 生产环境配置 if (isProduction) { // 生产环境注入 cdn config.plugin('html') .tap(args => { args[0].cdn = cdn; return args; }); } }, configureWebpack: smp.wrap({ module: { rules: [ { test: /\.js$/, use: ['thread-loader'] } ] }, plugins: [ new BundleAnalyzerPlugin() ], //生产环境注入 cdn externals: isProduction && { 'vue': 'Vue', 'vuex': 'Vuex', 'vue-router': 'VueRouter', 'axios': 'axios', 'echarts': 'echarts', 'swiper': 'Swiper' } || {}, optimization: { minimizer: [ new TerserPlugin({ parallel: 4 }) ] } }) }
2.4、使用 polyfill 动态服务
动态
polyfill指的是根据不同的浏览器,动态载入需要的
polyfill。
Polyfill.io通过尝试使用
polyfill重新创建缺少的功能,可以更轻松地支持不同的浏览器,并且可以大幅度的减少构建体积。
Polyfill Service 原理
识别 User Agent,下发不同的 Polyfill
使用方法:在
index.html中引入如下
script标签
<script crossorigin="anonymous" src="https://polyfill.io/v3/polyfill.min.js"></script>
三、完结
At last,看完之后有什么不懂的,可以留言反馈。
转载请注明出处:https://www.jianshu.com/p/481e7214a134
作者:TSY
个人空间:https://hxkj.vip
相关文章推荐
- vue项目中运用webpack动态配置打包多种环境域名的方法
- 解决webpack -p压缩打包react报语法错误的方法
- webpack 打包压缩js和css的方法示例
- webpack 代码优化压缩方法
- vue-cli与webpack处理静态资源的方法及webpack打包的坑
- vue-cli npm run build空白页的两个坑 webpack gzip文件压缩优化打包文件
- webpack打包静态资源和动态资源
- webpack打包生成多个vendor的配置方法
- Webpack实现按需打包Lodash的几种方法详解
- vue-cli webpack2项目打包优化
- 使用webpack打包ThinkPHP的资源文件
- 【视频】webpack打包机制及调试优化
- vue-cli webpack模板项目搭建及打包时路径问题的解决方法
- webpack配置:打包第三方类库、第三方类库抽离、watch自动打包、集中拷贝静态资源
- 优化单页面开发环境:webpack与react的运行时打包与热更新
- 详解用webpack把我们的业务模块分开打包的方法
- webpack+vuecli打包生成资源相对引用路径与背景图片的正确引用
- webpack打包分析与性能优化
- webpack下实现动态引入文件方法
- ASP.NET MVC优化--静态资源捆绑打包和压缩(Bundling and minification)提高页