公众号:程序员白特,可jia前端qun
背景
贴近目前公司的业务,做的增删改查比较多。基本上都是做一些表格的业务系统比较多,因此在写的过程中,都会遇到一些优化的细点,仅供参考,觉得好的可以采纳,不好的欢迎提出来。
一、import按需加载
很多小伙伴肯定不少看到过,性能优化路由要用import('@/views/xxxx.vue')
这样就可以按需加载了。
本身的vue-cli自动创建出来的时候也会有这一条语句。除了给路由优化之外呢,还有别的场景优化空间呢?那肯定有的啦。那就是结合<component/>
自带的组件去一起实现。
场景呈现
正常情况下,做一个业务模块,都会分为【基础表】、【业务表】,一般情况下,用户维护好了基础表信息了之后,剩下的就是信息交叉复用,有可能在某个业务页面,我需要点击某个按钮后根据某个值到某个基础表的页面进行搜索信息,并勾选行信息。
<template><div><div class="count" @click="showDynamicComponent">按需加载页面</div> <Modal title="动态数据" :visible="visible" @ok="()=>dynamicComponent=null"><component :is="dynamicComponent" ref="dynamicRef"/></Modal></div>
</template><script>
import { Modal } from 'ant-design-vue'
export default {components: {Modal},data() {return {dynamicComponent: null,visible: false};},methods: {showDynamicComponent() {this.visible = trueimport('@/views/baseInfo/a.vue').then(res=>{this.dynamicComponent = res.module})},},
};
</script>
最后通过this.$refs.dynamicRef
这个方式来拿到组件的信息和方法。
当然如果只引入一个组件的时候,可以不采用上面的方式进行。可以使用这种。
<template> <dynamicComponent ref="dynamicComponentRef"/>
</template><script>
// import dynamicComponent from '@/components/dynamicComponent.vue'; // 原来的引入
const dynamicComponent = () => import('@/components/dynamicComponent.vue')export default {components: {dynamicComponent}
}
</script>
二、表格维护
因为公司的做的系统报表比较多,这时候表头的数量和表单都是比较多的,恰好公司使用的UI框架是ant-design-vue
,表头的数量达到40-50的时候,那么代码的占用函数就很大,而且在产品经常在开发阶段,定义的表头位置顺序变来变去,于是为了方便维护和开发,我封装成一个函数,我还没考虑过这个性能损耗问题,但是维护起来确实方便很多。
业务场景
举个例子,一个表头有用户
、姓名
、年龄
,正常情况下,ant-design-vue
表头是这么写的。
const columns = [{dataIndex: 'username',title: '用户'
}, {dataIndex: 'realname',title: '姓名'
}, {dataIndex: 'age',title: '年龄'
}]
数据少的时候,维护没有什么问题,倒是表头数量很多的时候,可能40-50个,一百个?大概是这个数,看起来就很费劲。因为自己业务确实遇到过这个问题,维护起来要么单独创建一个文件大概一百多行一点点找,要么就放在业务代码里,但是无论如何阅读性都很差。所以我想了个办法,把它平铺变成数组形式。
import { genTableColumnsUtil } from '@/utils/tableJs'
const columns = genTableColumnsUtil([['username', '用户'],['realname', '姓名'],['age', '年龄'],
])
这时候是不是就好看多了?甚至这个可以做成二级表头,递归做嵌套。那额外的配置项拓展项怎么搞?
const columns = genTableColumnsUtil([['username', '用户'],['realname', '姓名'],['age', '年龄'],
],
{username: { width: '20%' }})
我的做法就是在函数里面在传多一个对象,这样就可以填充上去了。毕竟大多数字段只是展示而已,没有做太多的单元格定制化,如果要定制化,搜索对应的dataIndex
就好了。
这时候调整顺序的时候,还有定制化的时候就阅读性就好很多。
三、依赖包单独抽离
性能优化不只是代码层面的优化,除了nginx
配置http2
,gzip
… 单独抽离chunk包也可以达到加快访问速度的目的。
业务场景
// 在vue.config.js加入这段代码
module.exports = {configureWebpack: config => {// 分包,打包时将node_modules中的代码单独打包成一个chunkconfig.optimization.splitChunks = {maxInitialRequests: Infinity, // 一个入口最大的并行请求数,默认为3minSize: 0, // 一个入口最小的请求数,默认为0chunks: 'all', // async只针对异步chunk生效,all针对所有chunk生效,initial只针对初始chunk生效cacheGroups: { // 这里开始设置缓存的 chunkspackVendor: { // key 为entry中定义的 入口名称test: /[\\/]node_modules[\\/]/, // 正则规则验证,如果符合就提取 chunkname(module) {const packageName = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)[1]return `${packageName.replace('@', '')}`}}}}}}
}
最后在打包完了之后。可以查看一下。
四、thread-loader打包
业务场景
充分利用cpu核心数,进行快速打包、其实我也没感觉有多快。
// 开启多线程打包
config.module.rule('js').test(/\.js$/).use('thread-loader').loader('thread-loader').options({// worker使用cpu核心数减1workers: require('os').cpus().length - 1,// 设置cacheDirectorycacheDirectory: '.cache/thread-loader'}).end()
五、ECharts按需使用
业务场景
数字化是趋势,图形可视化在所难免,但往往我们有时候没做那么复杂的图形,可能只用到了饼图和柱状图,或者别的,怎么样都用不完ECharts
更多的图形,ECharts
是大家常用的图形化之一,ECharts
第一步教程都是告诉我们,在vue
文件里
import * as echarts from 'echarts'
殊不知,我们用不到的图形都加载进来,打包的时候就可以看到,这玩意,3M多。 所以,看情况来加载图形配置
import * as echarts from 'echarts/core'import { BarChart, LineChart, PieChart } from 'echarts/charts'import {TitleComponent,TooltipComponent,GridComponent,LegendComponent,ToolboxComponent,
} from 'echarts/components'import { CanvasRenderer } from 'echarts/renderers'echarts.use([TitleComponent,TooltipComponent,GridComponent,BarChart,LineChart,PieChart,CanvasRenderer,LegendComponent,ToolboxComponent
])export default echarts
通过vscode
的包插件,可以看到引入的模块大小
六、Tree shaking
每次百度,“vue性能优化”,“前端性能优化”…都会出现tree shaking
关键词,这玩意到底是啥呢?
得益于ES6的模块特性,模块依赖关系是确定的,同时和运行时的状态无关,所以可以进行可靠的静态分析,这就是tree-shaking。
大白话的说就是——
项目只会打包用到的代码。比如你写一个方法A,我用到了A函数,那我就打包进来,否则不打包。
有时候我们会这样写,这样写当然也没啥问题。只是性能优化上不太友好
export default {A() {return 'A' },B() {return 'B'},
}
至于怎么做呢?最简单的方式就是拆分,以函数为例。
// util.js// 导出A方法
export function A() {return 'A'
}
// 导出B方法
export function B() {return 'B'
}
大家可以尝试一下,在dist
包里面搜索一下对应方法名。
七、图片转base64
将图片转成base64的目的其实就减少http请求,当然图片可以放到云端、阿里云、七牛云来减小图片的体积大小。转成base64,其实体积会变大的,但是有些图片占用体积比较小的,可以将其转成base64,加快网页加载。
// 安装
npm install url-loader --save-dev// 配置
module.exports = {module: {rules: [{test: /.(png|jpg|gif)$/i,use: [{loader: 'url-loader',options: {// 小于 10kb 的图片转化为 base64limit: 1024 * 10}}]}]}
};
以上是个人反复写业务的时候思考的地方,没考虑太全面,也希望有人能提出一个更好的解决办法。愿意倾听改正。共勉、共勉,😁😁😁