vue常见优化手段(上)

上篇主要提及开发vue.js项目中的最佳实践,最佳实践通常可以规避错误,同时大幅提高应用的性能,下篇主要提及了开发vue.js项目中的风格规范,良好的风格规范可以改善可读性和开发体验

指令

我们从vue指令开始,逐步理解开发vue.js中的最佳实践并且知道它们为什么好,好在哪里

key

key这个特殊属性主要用在vue中进行虚拟DOM比对算法中,在对比新旧虚拟节点时分辨哪些节点被移动,新增或者删除

v-for

vue官方一直十分推荐在v-for中设置key属性,因为vue的默认更新策略是就地更新,即当依赖的数组发生改变时,哪怕只是移动了其中某一个元素的顺序,vue在虚拟DOM中也不会相应的移动对应节点,而是删除后重新生成对应顺序的节点

key的作用就是在更新子节点时,通过key来查找对应节点,那么查找的顺序就会快上很多,而且也不会发生上述删除,新增节点的情况,vue会尽可能的复用现有节点

<div v-for="item in items" :key="item.id">
	<div>{{item.value}}</div>
</div>

v-if/v-else-if/v-else

如果一组v-if和v-else的元素类型相同,那么在状态发生变化的时候生成的虚拟节点可能即是v-if上的,也有可能是v-else上的, 在默认情况下,vue会尽可能的复用已有元素,所以当两个本不相同的元素被识别为相同,则可能会出现意料之外的问题

通过添加key的形式让vue在对比虚拟节点时将其认为是两个不同的节点,从而避免意料之外的问题

<div v-if="isShow" key="show-true">
	{{show}}
</div>
<div v-else key="show-false">
	{{show}}
</div>

v-show or v-if

对于频繁切换显示状态的元素,使用v-show可以保证虚拟DOM的稳定,避免频繁的新增和删除元素,特别是对于那些内部包含大量dom元素的节点,这一点极其重要

v-if and v-for

我们应该避免将v-if和v-for一起使用,当vue处理指令时,v-for会比v-if有着更高的优先级,所以我们哪怕只是只渲染列表中的一部分元素,也得在重渲染的时候遍历整个列表

我们通常会有两种解决方法

  1. 如果是本就不该渲染的列表,我们可以通过将v-if放入其列表更上一层的容器中

    <div v-if="show">
    	<div v-for="item in items">
    		{{item}}
    	</div>
    </div>
    
  2. 如果我们需要过滤列表中的部分元素,我们可以通过计算属性来获得一个过滤后的列表
    代码省略

通过这些操作,我们遍历列表时的效率将会更高效,解耦了渲染层的逻辑,可维护性,可扩展性也会更强

非实时绑定的表单

当我们使用v-model来绑定一个表单项时,当用户改变表单项的状态时,数据会随着改变,vue也会发生重渲染,当用户输入十分频繁时这会带来一些性能的开销

我们可以通过使用 lazy 或不使用 v-model 的方式解决该问题,但要注意,这样可能会导致在某一个时间段内数据和表单项的值是不一致的
但注意,这个优化并不是一定的,需要根据具体业务的不同来进行取舍

<input v-model.lazy="value"/>
<!-- or -->
<input @change="change"/>

路由切换组件不变

这个问题我们在开发vue项目时会经常遇到,即当页面切换到同一个路由但参数不同的地址时,组件的生命周期钩子不会重新触发

这是因为vue-router会识别出两个路由为同一个组件从而进行复用,并不会重新创建组件,重新销毁并创建一个组件是十分消耗性能的

我们可以有以下几个方法来解决这个问题:

  1. beforeRouteUpdate
    vue-router提供了导航守卫相关的api,这些api会在路由改变时调用,所以我们可以将每次切换路由时重新执行的逻辑放在beforeRouteUpdate中

  2. watch
    我们也可以通过监听route对象发生的变化来做出对应的操作,但如果监听整个route对象会带来额外的内存开销,还会导致相关逻辑的耦合,更加推荐的做法是只观察自己组件需要的query,以减少不必要的逻辑
    不好的写法

    watch: {
    	'$route'(to, from){
    		//其他请求
    		//其他请求
    	}
    }
    

    推荐的写法

    watch: {
    	'$route。query.id'(to, from){
    		//其他请求
    	},
    	'$route。query.page'(to, from){
    		//其他请求
    	}
    }
    

延时加载

在最开始访问页面时,如果页面的组件太多,会导致页面白屏很长时间,一个可行的办法就是延迟装载组件,让组件按照指定的先后顺序依次一个一个染出来

延迟装载是一个思路,本质上就是利用 requestAnimationFrame 事件分批渲染内容,它的具体实现多种多样

let frameCount = 0;
export const refreshFrame = (maxCount) => {
    requestAnimationFrame(() => {
        frameCount++;
        if (frameCount < maxCount) {
            refreshFrame(maxCount);
        }
    });
}
export const defer = (showCount) => {
    return showCount >= frameCount
}

我们可以首先调用refreshFrame之后通过调用defer方法来达到延时加载的目的

  • 8
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值