Vue 项目性能优化
现在Vue3.0都快发布了为什么还要优化2.0的项目?因为市场上公司90%的项目全是Vue2.0的项目,迁移的话成本太高,所以只能进行性能的优化调整。废话就不多赘述了,直接开始吧。
一、活用异步组件
Vue-cli
打包的时候会把所有依赖的文件打包成一个很大的一个js
文件中,当用户浏览网页的时候需要把整个js
文件拉取过来,这样会导致页面在初始化的时候,页面会出现长时间的白屏情况,这个问题确实是蛮棘手的。
设想一下如果在页面中有很多的功能点,每个功能点又对应着不同的功能弹窗或者表单,首先第一点页面中的功能很多,我们不知道用户想要使用哪个功能,需要弹出哪个弹窗或表单,如果异步组件的情况,Vue-cli
在打包的时候会把异步组件单独打包成一个文件,当用户使用的才会去加载这个js
文件内容,这样无论是首屏的渲染起到了一定的优化的作用。
看下官网对于异步组件的说明:
在大型应用中,我们可能需要将应用分割成小一些的代码块,并且只在需要的时候才从服务器加载一个模块。为了简化,Vue允许你以一个工厂函数的方式定义你的组件,这个工厂函数会异步解析你的组件定义。Vue 只有在这个组件需要被渲染的时候才会触发该工厂函数,且会把结果缓存起来供未来重渲染。
// 代码截取自Vue官网
Vue.component('async-webpack-example',
() => import('./my-async-component')
)
Vue官方为了解决组件加载时的等待过长,提供了异步组件加载Loading的异步组件:
// 代码截取自Vue官网
const AsyncComponent = () => ({
// 需要加载的组件 (应该是一个 `Promise` 对象)
component: import('./MyComponent.vue'),
// 异步组件加载时使用的组件
loading: LoadingComponent,
// 加载失败时使用的组件
error: ErrorComponent,
// 展示加载时组件的延时时间。默认值是 200 (毫秒)
delay: 200,
// 如果提供了超时时间且组件加载也超时了,
// 则使用加载失败时使用的组件。默认值是:`Infinity`
timeout: 3000
})
二、组件按需引入
使用的一些第三方库可以通过按需引入的方式加载。避免引入不需要使用的部分,无端增加项目体积。比如在使用element-ui库的时候,可以只引入需要用到的组件。
三、组件内部请求数据
大家在做业务的时候,可能会有这种情况,当点击按钮之后,需要获取到该条数据的详情渲染到弹窗或者侧滑中,这种情况一定不在少数啦。开始做这个的时候就是,在点击的时候直接去获取点击的元素的详情数据,当数据返回之后把数据放到data
中缓存,之后再传到组件中。
这样做不是不可行的,也是可以的,这样就会面临一个问题,第一点就是当弹窗中的渲染的元素过多的情况下,侧滑或者弹窗的动画效果会很卡,有的时候甚至是不动,瞬间就消失了。
最后经过反复的实验,把数据放到弹窗内部组件中去请求,保证弹窗或者侧滑出现的时候内置元素较少,当数据没有请求回来之前需要把弹框组件内的所有元素隐藏,使用loading
代替,当弹窗或者侧滑关闭的使用需要把显示的组件销毁掉,保证里面的数据所占用的内存被释放,这样对于整体优化还是有一些帮助的。
四、tamplate少计算
由于业务情况的复杂程度,难免会某一个地方添加各种条件的渲染,例如:v-if="isHide && selectList.length && (isA || isB)"
,这里也只是举一个简单的栗子可能在实际的开发过程中的情况远比这个要复杂的多,这种表达式看上去虽然说是可以维护的,但是长此以往下去就会暴露问题,这样做是很不利于维护的。
对于这种情况可以适当的使用methods
或computed
封装成方法,其实这样做的好处是方柏霓我们判断相同的表达式,如果其他的元素也有类似的需求可以直接使用这个方法。
五、v-for循环设置key值
在用v-for进行数据遍历渲染的时候,为每一项都设置唯一的key值,为了让Vue内部核心代码能更快地找到该条数据,当旧值和新值去对比的时候,可以更快的定位到diff。
六、Object.freeze
如果对Vue有一定了解的小伙伴都知道Vue是通过Object.defineProperty
对数据进行挟持,来最终实现视图响应数据的变化,但是在实际的开发过程中,页面中有一部分可能不需要进行双向绑定,只是做单纯的渲染,数据一旦绑定之后不需要再做出任何改变的时候可以使用Object.freeze
对数据做解绑。
先介绍以下Object.freeze
内置函数,用于对接对象,冻结后的对象不会在被修改,不能对这个对象进行添加新属性, 不能删除已有属性,不能修改该对象已有属性的可枚举性,可配置性,可写性.此外冻结一个对象后该对象的原型也不能进行修改。
当数据量大的时候,这能够很明显的减少组件初始化的时间,这里有一个需要注意的点就是一旦被冻结的对象就再也不能被修改了。但是这里有一个问题需要注意的是,虽然Object.freeze
在一定程度上能够帮助我们提升一部分的数据性能,但是在使用的时候仍然需要谨慎使用。避免造成数据无法响应的问题。如果使用Object.freeze
这个属性再次给其对象属性赋值时,则会抛出错误不能分配给对象的只读属性*。
用这种方法去提升性能如果数据量小的情况是无法感觉出来的。只有数据量大的时候,才会感觉到数据的明显变化。
七、渲染前处理
在渲染数据的时候,后端所返回的数据和UI设计图中所需要的数据格式不一致,比如:列表中需要展示一个时间,但是后端返回的是一个时间戳,那么前端就需要对这部分数据进行处理。一般来说处理这种情况有一些办法,使用函数,使用filter
,还有就是在渲染之前把数据处理好。
笔者这里比较建议在渲染之前把所有的数据处理好,为什么?数据渲染之后完成之后才会去执行里面的函数或者是过滤器,这样会给页面渲染造成很明显的额外的负担。如果对Vue3.0
了解的同学可以知道,在Vue3.0
中已经把filter
这个功能已经去掉了,推荐使用computed
来实现相同相同的效果。
八、代码模块化
把很多常用的地方封装成单独的组件,在需要用到的地方引用,而不是写过多重复的代码,每一个组件都要明确含义,复用性越高越好,可配置型越强越好,包括咱们的css
也可以通过less
和sass
的自定义css
变量来减少重复代码。
九、Vue路由设置成懒加载
当首屏渲染的时候,能够加快渲染速度。
十、去var全局变量操作
去var
操作,不要造成内部泄漏,使用过后的全局变量在组件销毁后重新置为null
。
十一、使用cdn的方式外部加载一些资源
比如vue-router
、axios
等Vue
的周边插件,在webpack.config.js
里面,externals
里面设置一些不必要打包的外部引用模块。然后在入门文件index.html
里面通过cdn的方式去引入需要的插件。