去年接手了公司一个项目,前一段时间,收到产品反馈说线上打开菜单非常的慢,点了几个列表页,网站就卡死了,再点击就没有反应了。用的 vue2.6.10 + webpack3 + element-ui2.15.7 项目很大,业务代码中使用了很多体积比较大的库,还有封装了大量的组件。
本地构建花费了 5 分钟,打包完 dist 文件有 16M 这么大,首屏加载大概有 7-8s,打开项目线上地址,我进去一看点了几个页面,果然出现产品和用户反馈的一样,卡顿明显,没几分钟,整个网站卡住了,刷新也还是卡。
那就开始整吧。
如何排查问题
使用 chrome 的开发者工具(打开网站,按 F12)
如何使用可看官网文档,这里不赘述了
https://developer.chrome.com/docs/devtools/evaluate-performance/
Performance
Lighthouse
Network
勾选 Preverse Log 保留日志,勾选 Disable Cache 屏蔽浏览器的接口缓存机制,No throtting 选择器 slow3G 可以对当前网络状态进行检测,查看接口的响应体积和顺序
npm run preview – –report 来分析 webpack 打包之后的各个静态资源的大小。你可以发现占用空间最多的是第三方依赖,前提是安装了包 webpack-bundle-analyzer
接口慢
因为这部分需要后端同事协助,所以在我发现存在一部分接口没有分页,前端数据量很大,记录下接口地址,然后开会和后端负责人讨论改造工作。(工作需要及时的安排和协调,让前后端同事工作并行,效率会比较高。
经接口调整后,接口整个速度都更上去了,页面卡顿有所缓解
减少 HTTP 请求
升级 webpack
之前的项目结构
1 | yarn upgrade webpack@5.37.0 |
由于各种考虑 vue 和 element-ui 没有升级
1 | // package.json |
webpack.base.conf.js
1 | - const merge = require('webpack-merge') |
新增 mode 选项
1 | module.exports = { |
1 | + const VueLoaderPlugin = require('vue-loader/lib/plugin'); |
webpack.dev.conf.js
新增 mode 选项
1 | module.exports = { |
webpack.prod.conf.js
1 | - const ExtractTextPlugin = require('extract-text-webpack-plugin') |
build/util.js
1 | const ExtractTextPlugin = require('extract-text-webpack-plugin') |
splitChunks 分离代码后,过大的插件被提取出来
合理使用缓存
- 静态图片和字体尽量缓存
- cdn
1 | const isProduction = process.env.NODE_ENV === 'production'; |
找到 public/index.html。将 js 和 css 资源注入。
1 | <head> |
文件压缩 - 图片压缩
免费的 web 端工具TinyPNG将 images 拖进去,替换掉你的图片,尺寸大幅度压缩并保证质量。
gzip 压缩
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15if (config.build.productionGzip) {
const CompressionWebpackPlugin = require('compression-webpack-plugin');
webpackConfig.plugins.push(
new CompressionWebpackPlugin({
asset: '[path].gz[query]',
algorithm: 'gzip',
test: new RegExp(
'\\.(' + config.build.productionGzipExtensions.join('|') + ')$'
),
threshold: 100,
minRatio: 0.8,
})
);
}折腾到这里,构建速度 40 左右,dist 压缩到 4M。首屏加载控制在 1s。效果显著!
组件升级,支持虚拟加载
老项目中,使用 el-select,el-table 都不支持大数据虚拟加载,低版本存在卡顿现象
封装列表组件比较费时费力,版本 element-ui plus 支持虚拟加载。目前仅 keep-alive 来降低 dom 渲染消耗