-
背景
优化是起初是因为项目在测试环境首屏在测试环境加载过长,测试同学吐槽,然后着手优化的,说干就干,优化搞起来,首屏优化对用户体验还是很重要的。
-
分析现状
项目是用的 vue-cli4.5 版本,下面是 devlopment 环境打包后的结构
├─ dist
│ ├─ assets
│ │ └─ js
│ │ ├─ app.js
│ │ └─ chunk-vendors.js
│ ├─ favicon.ico
│ └─ index.html
未优化前的体积,总共加起来有5.43M 挺大的
同事安利了一款 webpack-bundle-analyzer 神器分析代码,可以直观的看到文件中的依赖和大小。下面工具分析后的图,工具用法自行看文档。推荐大家使用。
app.js 主要是一些业务相关的代码。size: 3.56M
chunk-vendors.js 主要是一些第三方的依赖文件。size:1.83M
工具调试代码如下,仅供参考:
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
plugins.push(new BundleAnalyzerPlugin(
{
analyzerMode: 'server',
analyzerHost: '127.0.0.1',
analyzerPort: 8889,
reportFilename: 'report.html',
defaultSizes: 'parsed',
openAnalyzer: true,
generateStatsFile: false,
statsFilename: 'stats.json',
statsOptions: null,
logLevel: 'info'
}
))
复制代码
问了下同事,说测试环境方便调试,路由没用懒加载,用的require方式导入,生产动态切换路由懒加载。
由于在打包优化方面也没太多经验,然后疯狂百度,查阅webpack 文档和 vue-cli文档,相关资料调试。
以下是分析和观察到一些问题:
- area.js 存储到资源服务器,目前是七牛云
area.js 这里很多个是因为业务特殊原因,需要动态切换省市县层级,area目录也有215k。
优化area之后的:
- 第三方插件 cdn 引入
修改 vue.config.js chainWebpack 配置
vue.config.js 文件
//第三方库cdn外部引入,减少打包体积
config.set('externals', {
vue: "Vue",
'vue-router': 'VueRouter',
vuex: 'Vuex',
axios: "axios",
swiper: 'Swiper',
vant: 'vant'
})
复制代码
HTML
<!DOCTYPE html>
<html lang="en">
<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, maximum-scale=1.0, minimum-scale=1.0, viewport-fit=cover" />
<link rel="icon" href="https://juejin.cn/post/<%= BASE_URL %>favicon.ico">
<link rel="stylesheet" href="https://at.alicdn.com/t/font_2423676_hx4ccbq3p0r.css">
<link rel="stylesheet" href="https://unpkg.com/swiper@5.3.8/css/swiper.css" />
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/vant@2.12/lib/index.css"
/>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6/dist/vue.min.js"></script>
<script src="https://cdn.bootcss.com/vue-router/3.0.2/vue-router.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/vuex/3.2.0/vuex.min.js"></script>
<script src="https://cdn.bootcss.com/axios/0.18.0/axios.min.js"></script>
<!-- 引入 Vue 和 Vant 的 JS 文件 -->
<script src="https://cdn.jsdelivr.net/npm/vant@2.12/lib/vant.min.js"></script>
<script src="https://unpkg.com/swiper@5.3.8/js/swiper.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue-awesome-swiper/dist/vue-awesome-swiper.js"></script>
<script type="text/javascript">
Vue.use(window.VueAwesomeSwiper);
</script>
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled.
Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
<script src="https://res2.wx.qq.com/open/js/jweixin-1.2.0.js"></script>
</html>
复制代码
优化之后:
好家伙:vender.js 减少了700多k
- 压缩代码,目前只是在生产做压缩,本地调试不方便就没压缩了
configureWebpack 加入代码
config.mode = 'production'
let prodPlugins = [
// 压缩js/css/html
new CompressionPlugin({
// filename: '[path].gz[query]',// 目标文件名
// algorithm: 'gzip',// 使用gzip压缩
test: /\.js$|\.html$|.\css/, // 匹配文件名
threshold: 10240, // 对超过10k的数据压缩
minRatio: 0.8, // 只有压缩率比这个值小的资源才会被处理
deleteOriginalAssets: true // 不删除源文件
})
]
复制代码
- 删除 prefetch 具体可看 vue-cli 配置,chainWebpack中加入
// 移除 prefetch 插件,避免占用多余的带宽
config.plugins.delete('prefetch');
复制代码
- 去掉console.log,目前生产开启
chainWebpack 中修改
//去除console.log代码
if(process.env.NODE_ENV === 'production') {
config.optimization
.minimizer('terser')
.tap(args => {
Object.assign(args[0].terserOptions.compress, { // 生产模式 console.log 去除
// warnings: false , // 默认 false
// drop_console: ,
// drop_debugger: true, // 默认也是true
pure_funcs: ['console.log']
})
return args
})
}
复制代码
目前只在生产能看到效果,因为本地打包后,发现生成的文件都没prefetch 的,生产的话就一次性prefeth 所有chuck块。
-
生产环境效果走起
主要还是以 生产环境 为基准:看看优化前后效果
优化前的:1.14M
优化后的:725.11kb
生产大小优化了 414.89 kb,效果还是有的。
-
总结
经过这次项目优化,对webpack 配置更加了解了,学到很多。比如路由懒加载,开发和生产环境如何权衡优化。优化的道路还很长,还有很多要学;觉得有用的话,麻烦大佬们点个赞吧。