虚拟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,为什么说他快?的主要内容,如果未能解决你的问题,请参考以下文章

[react] 为何说虚拟DOM会提高性能?

虚拟DOM如何进化为真实DOM

DOM操作的性能优化

什么是虚拟DOM?为啥虚拟DOM可以提升性能?

面试官: 你对虚拟DOM原理的理解?

JS性能DOM优化