写在前面: 在公司负责运营平台的开发工作,随着业务代码越来越多,首屏渲染越来越慢,记录下自己是如何解决问题的
发现问题
线上首屏渲染慢,原因是由于首屏渲染请求静态资源达到30M,如此之大的静态资源确实让人无法容忍,于是开始从路由组件和内部业务组件按需加载,webpack的tree-shaking 和代码压缩、静态资源浏览器缓存几个方向开始排查,同时基于webpack-bundle-analyzer对现有的打包后的资源进行大小分析
解决问题
业务组件异步加载
在vue3中,对于业务组件的异步加载和vue2略有不同,
- vue2是在局部注册中使用下面的代码
components: {
EditForm: () => import('@/components/newEditForm/index'),
}
- vue3中则是基于
defineAsyncComponent函数
import {defineAsyncComponent } from "vue";
components: {
EditForm: defineAsyncComponent(() => import('@/components/newEditForm/index')),
}
打包后资源的大小分析
基于webpack-bundle-analyzer webpack插件实现对打包后的代码进行大小分析,详细配置如下vue.config.js
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
module.exports = {
chainWebpack: config => {
config.plugin('webpack-bundle-analyzer').use(BundleAnalyzerPlugin);
}
};
这样即可实现每次build都能起一个8088的端口,将打包后代码的大小分析呈现在网页上
代码压缩
基于uglifyjs-webpack-plugin webpack插件实现对打包后的代码进行大小分析,详细配置如下vue.config.js
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
module.exports = {
configureWebpack: config => {
const optimization = {
minimizer: [
new UglifyJsPlugin({
uglifyOptions: {
compress: {
drop_console: true,
drop_debugger: false,
// collapse_vars: true,
// reduce_vars: true,
},
output: {
beautify: false,
comments: false,
},
},
}),
],
};
Object.assign(config, {optimization});
}
};
这样每次代码build都会将代码压缩一遍
浏览器强制缓存
对现有的静态资源请求进行强缓存,由于每次打的bundle包名称都有hash值,这样每次改动后打的包名称都会有区别,不会出现打包后浏览器未更新的情况
清除webpack中的prefetch配置
在做完异步加载,缓存,代码压缩后,还是发现首屏加载js资源并未减少,检查发现是在vue3+webpack4中,webpack默认开启了prefetch配置,打包出的html中用的link和script都默认加上了rel=prefetch, 该属性会导致在第一次加载时就将所有具有该属性的资源都拉下来,更改vue.config.js即可
module.exports = {
chainWebpack: config => {
config.plugins.delete('prefetch');
}
};
最后
基于上述方法优化后,首屏加载静态资源缩小了十倍,速度提升了90%,效果还是很可观的。