虚拟DOM性能优化实战,同样是操作DOM,为什么说他快?
Posted 前端之阶
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了虚拟DOM性能优化实战,同样是操作DOM,为什么说他快?相关的知识,希望对你有一定的参考价值。
为什么说虚拟DOM快?
虚拟DOM不会进行排版与重绘操作
虚拟DOM进行频繁修改,然后一次性比较并修改真实DOM中需要改的部分(注意!),最后并在真实DOM中进行排版与重绘,减少过多DOM节点排版与重绘损耗
真实DOM频繁排版与重绘的效率是相当低的
虚拟DOM有效降低大面积(真实DOM节点)的重绘与排版,因为最终与真实DOM比较差异,可以只渲染局部(同2)
使用虚拟DOM的损耗计算:
总损耗=虚拟DOM增删改+(与Diff算法效率有关)真实DOM差异增删改+(较少的节点)排版与重绘
直接使用真实DOM的损耗计算:
总损耗=真实DOM完全增删改+(可能较多的节点)排版与重绘
总之,一切为了减弱频繁的大面积重绘引发的性能问题,不同框架不一定需要虚拟DOM,关键看框架是否频繁会引发大面积的DOM操作。
虚拟DOM优化实战
如果我有1000条数据,我修改了其中两条,真实的DOM会重新渲染1000条数据,只要发生了变化,就会重新渲染全部数据,虚拟dom 会生成1000个对象 (它是不会被浏览器图形化渲染的),虚拟dom 里的东西会和真实dom绑定在一起,当数据发生变化 虚拟dom和之前的虚拟dom 会去做数据的比较,当数据发生变化时,才会去更新数据发生改变的那部分真实的dom元素
但是数组没有默认的标识,所以数组每次改变都要重新排序,性能影响较大,所以在实时侦听遍历数组数据时,需要引入key属性,用来标识数组数据,一般使用下标标识
<template>
<div>
<ul><!--遍历数组时,添加 key 属性是为了优化vnode-->
<li
v-for="(item,index) in list"
:key="index"
@click="list.push('laowang')"
>
{{item}}
</li>
</ul>
</div>
</template>
<script>
export default {
mounted() {
console.log(this);
},
data() {
return {
list: ["zhangsan", "lisi"]
};
}
};
</script>
<style>
</style>
下面我们谈一下DOM的key值,大家应该也在小程序,vue中遇到过for循环时,如果不给循环的标签一个key值,浏览器会console一个警告,那么这个key值究竟有什么用呢,以及为什么不建议用index做key值呢?
keys
左图描述了一个数组,我们在渲染的时候让数组中的5个数据生成了5个虚拟DOM树,这时我们新增加一个数据,由于我们没有给节点key值,所以当我们在做两个虚拟DOM比对时,节点与节点之间的关系就很难被确立,这点会损耗比对过程的性能。
所以建议大家一定要在循环中给节点加上key值,为什么不推荐用index做key值呢,原因在于两个虚拟DOM比对时,如果key值是固定的(如对象本身,如果是从数据库读取的数据,key值可以设置成这条数据的id),这时比对的效率会非常高。
假设使用index做key值,那么我们在删除一项数据的时候,会导致index值错位,如:
原始数据:A-0, B-1, C-2
这时我们删除A,数据变为:B-0, C-1
这样key值就失去了存在的意义,所以官方建议我们使用一个稳定的值去做key值。
以上是关于虚拟DOM性能优化实战,同样是操作DOM,为什么说他快?的主要内容,如果未能解决你的问题,请参考以下文章