首页>>前端>>Vue->Vue项目性能优化实操,从50分到80分

Vue项目性能优化实操,从50分到80分

时间:2023-12-01 本站 点击:0

分析性能

在进行具体的优化之前,我们需要借助工具,分析一下性能。以下操作推荐在浏览器无痕模式下进行,可以多测几次,取一个平均值,避免网络波动带来较大的误差!

chrome tools network 查看请求信息

lighthouse 收集网页性能指标

webpack-bundle-analyzer 查看打包模块依赖关系和包体大小

vue-cli3 是内置了webpack-bundle-analyzer插件,我们可以直接通过"build:report": "vue-cli-service build --report"命令生成report.html文件进行查看。

打包体积优化

从上图中可以看出,打包出来比较大的模块主要是moment,xlsx,quill,ant-design icon,针对这些插件都可以做出优化。

移除moment的所有本地文件

const webpack = require('webpack');module.exports = {   plugins: [     // 忽略 moment.js的所有本地文件     new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),   ], };

ant design vue 的 icon 按需加载

ant design vue提供的icon很多,打包出来有500+kb,其实很多我们都用不上,需要对其进行按需加载处理。

// antIcons.js// outLineexport { default as CopyOutline } from '@ant-design/icons/lib/outline/CopyOutline';export { default as CloseCircleOutline } from '@ant-design/icons/lib/outline/CloseCircleOutline';export { default as WarningOutline } from '@ant-design/icons/lib/outline/WarningOutline';// fillexport { default as ExclamationCircleFill } from '@ant-design/icons/lib/fill/ExclamationCircleFill';export { default as CloseCircleFill } from '@ant-design/icons/lib/fill/CloseCircleFill';export { default as CheckCircleFill } from '@ant-design/icons/lib/fill/CheckCircleFill';

// vue.config.jsmodule.exports = {    chainWebpack: (config) => {      config.resolve.alias        .set('@$', resolve('src'))        .set('@ant-design/icons/lib/dist$', resolve('src/plugins/antdIcons.js'));    }}

按需加载,会导致一些内部组件使用的icon丢失,也需要手动给它导入一下。

三方库 配置 CDN链接

// vue.config.jsconst assetsCDN = {  // webpack build externals  externals: {    vue: 'Vue',    'vue-router': 'VueRouter',    vuex: 'Vuex',    axios: 'axios',    xlsx: 'XLSX',    quill: 'Quill'  },  js: [    '//cdn.xxx.com/vue@2.6.0.min.js',    '//cdn.xxx.com/vue-router@3.5.3.min.js',    '//cdn.xxx.com/vuex@3.1.1.min.js',    '//cdn.xxx.com/axios@0.19.2.min.js',    '//cdn.xxx.com/xlsx.core.min.js',    '//cdn.xxx.com/quill_v1.3.6.min.js'  ]};module.exports = {  configureWebpack: {    // 打包时遇到这些externals,就不把它们打进去    externals: isProd ? assetsCDN.externals : {}  },  chainWebpack: (config) => {    if(isProd) {      // 把cdn的地址添加到index.html页面中      config.plugin('html').tap(args => {args[0].cdn = assetsCDN;return args;});    }  }}

externalskey-value的形式,keypackage.json中安装的包名,value是包真实注册或者说暴露的全局变量的值,比如vue-routervalueVueRouter,打开vue-router的源码,格式化可以看到如下,注册的值是VueRouter,其他的插件类似。

xlsx的处理

在用xlsx做前端导出excel功能时,网上大部分代码中都是用script-loader去加载xlsx的:

require('script-loader!xlsx/dist/xlsx.core.min');....

这样做并不能实现externals的功能,最后打包出来还是会引入一个xlsx.core.min.js文件,其实最新的xlsx已经支持import方式引入了:

import XLSX from 'xlsx'

cdn地址有条件的情况下,最好用公司内部的,预防第三方cdn失效,导致线上崩溃,不能使用。

图片压缩

yarn add image-webpack-loader -D

config.module.rule('images').use('image-webpack-loader').loader('image-webpack-loader').options({  bypassOnDebug: true}).end();

其实我更喜欢在拿到图片的时候,就用第三方工具压缩一下,还可以比较好的保证图片的清晰度。使用插件压缩,还会增加打包时间,看取舍吧。

推荐一个在线图片压缩,最高压缩可达80%,比插件的效果好。

打包时间优化

speed-measure-webpack-plugin 打包时间分析

yarn add speed-measure-webpack-plugin -D

// vue.config.jsconst SpeedMeasurePlugin = require("speed-measure-webpack-plugin");const smp = new SpeedMeasurePlugin();module.exports = {  configureWebpack: smp.wrap({      plugins: [        new MyPlugin(),         new MyOtherPlugin()      ],    });}

运行打包命令的时候就可以看到每个loaderplugin执行耗时:  

speed-measure-webpack-plugin,会大大加大打包的时间,所以部署上线的时候最好是注释掉。

Happypack 多进程打包

// antIcons.js// outLineexport { default as CopyOutline } from '@ant-design/icons/lib/outline/CopyOutline';export { default as CloseCircleOutline } from '@ant-design/icons/lib/outline/CloseCircleOutline';export { default as WarningOutline } from '@ant-design/icons/lib/outline/WarningOutline';// fillexport { default as ExclamationCircleFill } from '@ant-design/icons/lib/fill/ExclamationCircleFill';export { default as CloseCircleFill } from '@ant-design/icons/lib/fill/CloseCircleFill';export { default as CheckCircleFill } from '@ant-design/icons/lib/fill/CheckCircleFill';0

// antIcons.js// outLineexport { default as CopyOutline } from '@ant-design/icons/lib/outline/CopyOutline';export { default as CloseCircleOutline } from '@ant-design/icons/lib/outline/CloseCircleOutline';export { default as WarningOutline } from '@ant-design/icons/lib/outline/WarningOutline';// fillexport { default as ExclamationCircleFill } from '@ant-design/icons/lib/fill/ExclamationCircleFill';export { default as CloseCircleFill } from '@ant-design/icons/lib/fill/CloseCircleFill';export { default as CheckCircleFill } from '@ant-design/icons/lib/fill/CheckCircleFill';1

HardSourceWebpackPlugin 打包缓存

// antIcons.js// outLineexport { default as CopyOutline } from '@ant-design/icons/lib/outline/CopyOutline';export { default as CloseCircleOutline } from '@ant-design/icons/lib/outline/CloseCircleOutline';export { default as WarningOutline } from '@ant-design/icons/lib/outline/WarningOutline';// fillexport { default as ExclamationCircleFill } from '@ant-design/icons/lib/fill/ExclamationCircleFill';export { default as CloseCircleFill } from '@ant-design/icons/lib/fill/CloseCircleFill';export { default as CheckCircleFill } from '@ant-design/icons/lib/fill/CheckCircleFill';2

// antIcons.js// outLineexport { default as CopyOutline } from '@ant-design/icons/lib/outline/CopyOutline';export { default as CloseCircleOutline } from '@ant-design/icons/lib/outline/CloseCircleOutline';export { default as WarningOutline } from '@ant-design/icons/lib/outline/WarningOutline';// fillexport { default as ExclamationCircleFill } from '@ant-design/icons/lib/fill/ExclamationCircleFill';export { default as CloseCircleFill } from '@ant-design/icons/lib/fill/CloseCircleFill';export { default as CheckCircleFill } from '@ant-design/icons/lib/fill/CheckCircleFill';3

第一次打包时间没什么提升,但是第二次开始提升效果就很明显了。在node_modules/.cache中可以看到它的缓存文件。

首屏加载优化

分析 覆盖率 ,进行拆包splitChunks

Chrome DevTools 有一组平行的选项卡,被隐藏在主窗口之下。这个组合被称为 Drawer。 当你在 DevTools (任何选项卡)中时,按 [esc] 来显示它,再次按 [esc] 隐藏它:

通过上图我们可以看出chunk-vendors.js文件的未使用字节数(Unused Bytes)达到了97%,这表示首页加载的大部分js都是用不着的。

经过上面的优化,我们可以打包看一下包体分析: chunk-venders很大,它包含了大量的依赖库,ant-design-vue,vxe-table,moment等,我们可以通过splitChunks将这些第三方库进行抽离独立打包。

// antIcons.js// outLineexport { default as CopyOutline } from '@ant-design/icons/lib/outline/CopyOutline';export { default as CloseCircleOutline } from '@ant-design/icons/lib/outline/CloseCircleOutline';export { default as WarningOutline } from '@ant-design/icons/lib/outline/WarningOutline';// fillexport { default as ExclamationCircleFill } from '@ant-design/icons/lib/fill/ExclamationCircleFill';export { default as CloseCircleFill } from '@ant-design/icons/lib/fill/CloseCircleFill';export { default as CheckCircleFill } from '@ant-design/icons/lib/fill/CheckCircleFill';4

name: 打包的 chunks 的名字

test: 匹配到的模块奖杯打进这个缓存组

chunks: 代码块类型 必须三选一: “initial”(初始化) | “all”(默认就是 all) | “async”(动态加载)默认 Webpack 4 只会对按需加载的代码做分割。如果我们需要配置初始加载的代码也加入到代码分割中,可以设置为 ‘all’

priority: 缓存组打包的先后优先级,数值大的优先

minSize: 默认是30000)形成一个新代码块最小的体积

minChunks: (默认是1)在分割之前,这个代码块最小应该被引用的次数

maxInitialRequests:(默认是3)一个入口最大的并行请求数

maxAsyncRequests:(默认是5)按需加载时候最大的并行请求数

reuseExistingChunk: 如果当前的 chunk 已被从 split 出来,那么将会直接复用这个 chunk 而不是重新创建一个

enforce: 告诉 webpack 忽略 splitChunks.minSize, splitChunks.minChunks, splitChunks.maxAsyncRequests and splitChunks.maxInitialRequests,总是为这个缓存组创建 chunks

开启gzip

在nginx下开启gzip有两种方式:

gzip on 调用服务器cpu 动态打包

gzip_static on  使用前端已经打包好的gzip文件 更快

可以看一下[nginx官方文档配置]。(http://nginx.org/en/docs/http/ngx_http_gzip_static_module.html#gzip_static)

我们使用前端打好gzip文件,因为调用服务器cpu 动态打包,耗时间也耗性能,部署的时候前端打包好,就省时省力了。

// antIcons.js// outLineexport { default as CopyOutline } from '@ant-design/icons/lib/outline/CopyOutline';export { default as CloseCircleOutline } from '@ant-design/icons/lib/outline/CloseCircleOutline';export { default as WarningOutline } from '@ant-design/icons/lib/outline/WarningOutline';// fillexport { default as ExclamationCircleFill } from '@ant-design/icons/lib/fill/ExclamationCircleFill';export { default as CloseCircleFill } from '@ant-design/icons/lib/fill/CloseCircleFill';export { default as CheckCircleFill } from '@ant-design/icons/lib/fill/CheckCircleFill';5

// antIcons.js// outLineexport { default as CopyOutline } from '@ant-design/icons/lib/outline/CopyOutline';export { default as CloseCircleOutline } from '@ant-design/icons/lib/outline/CloseCircleOutline';export { default as WarningOutline } from '@ant-design/icons/lib/outline/WarningOutline';// fillexport { default as ExclamationCircleFill } from '@ant-design/icons/lib/fill/ExclamationCircleFill';export { default as CloseCircleFill } from '@ant-design/icons/lib/fill/CloseCircleFill';export { default as CheckCircleFill } from '@ant-design/icons/lib/fill/CheckCircleFill';6

其他代码优化

取公共组件, 公共代码(Mixins, Utils)

异步加载组件

// antIcons.js// outLineexport { default as CopyOutline } from '@ant-design/icons/lib/outline/CopyOutline';export { default as CloseCircleOutline } from '@ant-design/icons/lib/outline/CloseCircleOutline';export { default as WarningOutline } from '@ant-design/icons/lib/outline/WarningOutline';// fillexport { default as ExclamationCircleFill } from '@ant-design/icons/lib/fill/ExclamationCircleFill';export { default as CloseCircleFill } from '@ant-design/icons/lib/fill/CloseCircleFill';export { default as CheckCircleFill } from '@ant-design/icons/lib/fill/CheckCircleFill';7

路由懒加载

// antIcons.js// outLineexport { default as CopyOutline } from '@ant-design/icons/lib/outline/CopyOutline';export { default as CloseCircleOutline } from '@ant-design/icons/lib/outline/CloseCircleOutline';export { default as WarningOutline } from '@ant-design/icons/lib/outline/WarningOutline';// fillexport { default as ExclamationCircleFill } from '@ant-design/icons/lib/fill/ExclamationCircleFill';export { default as CloseCircleFill } from '@ant-design/icons/lib/fill/CloseCircleFill';export { default as CheckCircleFill } from '@ant-design/icons/lib/fill/CheckCircleFill';8

主要作用是将路由对应的组件打包成一个个的js代码块, 只有在这个路由被访问到的时候,才加载对应的组件,否则不加载!

最后

看一下优化的效果:

原文:https://juejin.cn/post/7101560677688410125


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:/Vue/5061.html