项目技术栈
1.vue 2.6.10
2.vue/cli 4.5.15
初始构建大小
初始build的结果如上图所示,整个dist文件夹大小是49.7MB,从文件上可以看到,app.js、0.js、2.js、3.js文件夹非常大,这种时候就要找找原因了
引入辅助工具
既然要分析这些比较大的文件里面都有些什么, 我们就引入一下分析包的工具,webpack-bundle-analyzer:
npm install --save-dev webpack-bundle-analyzer
接着在vue.config.js中要做一些配置
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
module.exports = {
configureWebpack: (config) => {
return {
//...
plugin: [
new BundleAnalyzerPlugin({
analyzerPort: 8889, // 分析页面
openAnalyzer: false // 默认不打开分析模块页面
})
]
//...
}
}
}
配置好了,看看效果,执行一下编译打包的命令
npm run build
编译完成之后,打开浏览器,地址栏输入localhost:8889
从上图就很明显看到哪些文件占的大。好了,接下来做一些针对性的解决方法吧。
优化一:cdn引入
首先让我很耿耿于怀的就是这个ercharts,确实用的多,打包之后也很占空间,所以我决定用cdn来引入:
public/index.html
<script crossorigin="anonymous" src="https://lib.baomitu.com/echarts/5.2.1/echarts.min.js"></script>
其它版本你们自己移步到链接: echarts
配置vue.config.js
module.exports = {
chainWebpack: config => {
// ...
var externals = {
'echarts': 'echarts',
}
config.externals(externals)
config.plugins.delete("prefetch") //配置可以取消首屏渲染时对组件js文件的预加载, 实现真正的按需加载
},
//...
}
使用方法
import * as echarts from 'echarts'
哪个页面需要用到,就按照上面的引入就行,也可以在main.js全局引入,这样就可以直接使用echarts.init()等方法了
重新打包看效果
我忘记截图了,你们可以自己看看效果哈,就echarts.js部分就没了,我这边是缩小了6MB
优化二:按需引入
按需引入的话,其实是编码习惯来的,有些项目为了方便,就在main.js中全局引用样式框架等,最后有没有用到其实也不知道,打包的时候还一起打包了,所以导致打包之后体积很大,在main.js中全局引用element-ui的童鞋看过来:
安装插件
npm install babel-plugin-component -D
配置babel.config.js
module.exports = {
presets: [
'@vue/app'
],
"plugins": [
[
"component",
{
"libraryName": "element-ui",
"styleLibraryName": "theme-chalk"
}
]
]
}
重新打包看效果
你们可以自己看看效果哈。
优化三:懒加载
经过前面两个步骤的优化之后我们会发现,虽然app.js是有变小,但是首屏加载整个app.js的时候,还是很慢,它还是很大,这种时候,我们应该去拆分它,使得每个页面只加载自己所需要的文件,就要用到懒加载啦!
先来看一段vue-router官网文字
当打包构建应用时,JavaScript 包会变得非常大,影响页面加载。如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就会更加高效
那就来试试:
router.js
const router = createRouter({
// ...
routes: [{ path: '/users/:id', component: () => import('./views/UserDetails')}],
})
接着我在vue.config.js中加一些配置,你们可配可不配,我就是为了打包之后js文件放在文件夹内
module.exports = {
configureWebpack: (config) => {
return {
//...
output: {
// 防止打包js不在js文件夹下,生成新的js名称防止缓存
filename: `js/[name].[hash].js`
},
plugin: [
new BundleAnalyzerPlugin({
analyzerPort: 8889, // 分析页面
openAnalyzer: false // 默认不打开分析模块页面
})
]
//...
}
}
}
打包看效果
打包之后发现js文件变多了,但是基本上体积都很小,部署之后也会发现速度快了很多,因为首屏需要加载的内容也不多,然后你会发现打包出来的很多js文件命名是0,1,2,3,4这种,你不知道对应那个页面的,这种时候,我们可以引入chunkFilename
修改一下router.js
const router = createRouter({
// ...
routes: [{ path: '/users/:id', component: () => import(/* webpackChunkName: "UserDetails" */'./views/UserDetails')}],
})
修改一下vue.config.js
output: {
filename: `js/[name].[hash].js`,
chunkFilename: `js/[name].[hash].js`
},
重新打包看效果
打包之后js文件命名就不是0,1,2…这种了,并且你会发现,同一个命名文件的页面,会打包到同一个js文件里面,看自己需求做哈,还有chunkname是可以动态设置的,有些项目的路由是遍历出来的,需要动态命名chunkname,有兴趣自己查一下哈
优化四:压缩文件
优化进行到这里,其实页面加载速度已经快了很多了,总体的文件还是比较大的,所以我们再搞一个压缩插件,引入compression-webpack-plugin
npm install compression-webpack-plugin -D
修改vue.config.js
const CompressionWebpackPlugin = require('compression-webpack-plugin')
module.exports = {
configureWebpack: (config) => {
return {
//...
new CompressionWebpackPlugin({
filename: '[path].gz[query]',
algorithm: 'gzip',
// test: new RegExp('\\.(' + productionGzipExtensions.join('|') + ')$'),
test: /\.js$|\.css$/,
threshold: 10240, // 只有大小大于该值的资源会被处理,当前配置为对于超过1k的数据进行处理,不足1k的可能会越压缩越大
minRatio: 0.99, // 只有压缩率小于这个值的资源才会被处理
deleteOriginalAssets: true // 删除原文件
}),
output: {
// 防止打包js不在js文件夹下,生成新的js名称防止缓存
filename: `js/[name].[hash].js`,
chunkFilename: `js/[name].[hash].js`
},
plugin: [
new BundleAnalyzerPlugin({
analyzerPort: 8889, // 分析页面
openAnalyzer: false // 默认不打开分析模块页面
})
]
//...
}
}
}
重新打包看效果
js和css压缩之后体积更小了
总结
—加载速度慢原因分析—:
1.懒加载只使用在部分路由上,导致没有用懒加载的部分全部打包之后塞在app.js文件中,首屏加载时app.js加载完使用的时长较长;
2.页面引用了很多其实没有实际用到的插件,导致打包之后插件的体积较大;
3.echarts和vue-echarts的重复引用;
4.没有按需引用插件,像elementui直接在main.js中use,但是没有做打包过滤没有用到的样式处理;
【优化前】1分15秒 49.7MB
【优化后】3.5秒 10.7MB
注意:优化体积大小变化不大,但是因为使用懒加载,不会存在像之前那种单个包十几个M的问题.
有问题的地方,请大家不吝指教!