Vue性能优化
函数式组件
1 .函数式组件生成的Vnode是普通的Vnode,模板生成的组件Vnode需要递归子组件的初始化过程,函数式组件不会有递归子组件的过程,渲染开销会低很多。
2 .函数式组件不会有状态,不会有响应式数据,生命周期钩子这种操作
3 .函数式组件
1 .不能管理任何状态
2 .无实例,组件自身没有实例,没有this
3 .没有生命周期方法
4 .只接收一些prop的函数
4 .快的原因
1 .没有状态,不需要响应式的额外初始化
2 .新传入的props,在组件本身中,无法知道数据什么时候发生变化,因为他不维护自身状态
3 .
5 .使用场景
1 .最简单的展示组件,整个页面都是静态文本,比如about页面
2 .v-for循环中的每一项
6 .基本方式
7 .事件定义
1 .没有事件定义,只能由父组件传参
8 .结论:我这边这个是改不了的
子组件拆分
1 .由于 Vue 的更新是组件粒度的,虽然每一帧都通过数据修改导致了父组件的重新渲染,但是 ChildComp 却不会重新渲染,因为它的内部也没有任何响应式数据的变化。所以优化后的组件不会在每次渲染都执行耗时任务,自然执行的 JavaScript 时间就变少了
2 .结论:我这里拆分也做了
局部变量
1 .this.base:每次调用的时候都会走一遍响应式绑定,出发getter,进而执行依赖收集相关逻辑代码
2 .也就是计算前,先把this.base这种调用的变量先缓存起来。const base=this.base.之后使用base。也就是说在一个函数里面都要这么搞
<template>
<div :style="{ opacity: start / 300 }">{{ result }}</div>
</template>
<script>
export default {
props: ['start'],
computed: {
base () {
return 42
},
result () {
let result = this.start
for (let i = 0; i < 1000; i++) {
result += Math.sqrt(Math.cos(Math.sin(this.base))) + this.base * this.base + this.base + this.base * 2 + this.base * 3
//错误的调用这里,在一个很大的循环里面不停的调用this.base
}
return result
},
},
}
</script>
3 .结论:这里没法搞,但是把一些原来写在data里面的数据移到了外面,mixin里面的数据,别的地方竟然访问不到。有点拉。这个数据没有被全局共享.
4 .vue不能在props里面传
v-show 复用DOM
1 .v-if 每次更新组件,都会重新生成组件
2 .初始的时候v-if更快。
3 .更新的时候是v-show比v-if快
4 .结论:这里必须用v-if。因为消失的表单不验证,除了自己检查,还有就是直接让他消失。dom直接消失,也是可以实现这个,而且更加保险。最关键我这里要的是初始加载速度,所以选择v-if
keep-alive缓存组件
1 .使用keep-alive后,被keep-alive包裹的组件在经过第一次渲染后,vnode以及DOM会被缓存起来。然后在下一次渲染组件的时候,直接从缓存中拿取对应的dom和vnode,然后渲染,并不需要再次走组件初始化,render,patch的逻辑,所以会很快
Deferred features
1 .使用Deferred组件延时分批渲染组件
2 .实际没有提高性能,只是把页面某部分功能先执行,某部分功能延迟处理,提高用户体验
image.png
image.png
批处理
1 .仅仅是分批commit数据
2 .
非响应式模式
1 .Vue内部提交数据的时候,会默认把新提交的数据也定义成响应式,如果数据的子属性是对象形式,还会递归让子属性也变成响应式,因此如果提交的数据很多,这个过程就变成了一个耗时的过程
2 .所以需要提交数据的时候,把对象的属性configurable为false,这样内部walk时通过Object.keys(obj)获取对象属性数组会忽略data,也就不会为这个data属性defineReactive。如果data是一个对象,也会减少递归响应的逻辑。数据量越大,影响约明显
3 .数据不需要定义在data里面。可以挂在在this上面这样就可以在上下文中共享一个对象了,尽管他不是一个响应式对象
其他问题
1 .mounted和computed谁先执行,如果mounted里面决定组件不执行,那么computed属性里面的逻辑,我就要停止掉
2 .vue不能在props里面传递配置的对象,所有的props必须是data,和computed里面返回的。这样数据就必须走响应式依赖收集那一套。但是我这里可能不需要啊。