前言
大家好,我是小杜杜,React
中的虚拟DOM和diff算法是非常核心的特型,了解它们是非常有必要,只有了解,才能深入。
我们直接来看看以下几个问题:
虚拟DOM
到底是什么,它与真实的DOM
有什么不同?- 在
React
中,为什么自定义组件的首字母要大写? - 有了
虚拟DOM
,性能就一定能够得到提升吗? - React的
diff算法
与传统的diff算法
有什么区别?为什么受到吹捧? diff策略
有哪些?它们是如何比较的?- 为什么在循环中不要用索引(index)做
key
值呢? - …
如果你对上述问题有疑问,那么这篇文章一定能够帮助到你~
跟之前一样先附上这篇的知识图,还请各位多多支持:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gi7s86Es-1658297236093)(https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/8f82868a39244b3281538fb9bf4c7103~tplv-k3u1fbpfcp-zoom-in-crop-mark:4536:0:0:0.image?)]
虚拟DOM
与真实DOM对比
结构对比
我们首先用React.createElement
和document.createElement
创建以下,然后进行打印,看一下,虚拟DOM和真实DOM有什么区别:
const VDOM = React.createElement('div', {}, '小杜杜')
const DOM = document.createElement("div");
DOM.innerHTML = '小杜杜'
console.log(`虚拟DOM:`, VDOM)
console.log(`真实DOM:`, DOM)
结果:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-X9o1tAxg-1658297236093)(https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/58db2ee32bde44b3afd5e2e6af3e3647~tplv-k3u1fbpfcp-zoom-in-crop-mark:4536:0:0:0.image?)]
我们可以看出虚拟DOM是一个对象的结构,而真实的DOM是一个dom的结构,而这个dom结构究竟是什么呢?我们可以通过断点去看看: [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XjLhjDST-1658297236093)(https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/c859397a03024903939f934907052cc2~tplv-k3u1fbpfcp-zoom-in-crop-mark:4536:0:0:0.image?)]
我们可以看到,在真实的DOM上,默认会挂载很多属性和方法,但在实际中,我们并不需要去关心这些属性和方法(注意:这些属性和方法是默认的,因为标准是这么设计的)
所以从结构上来看:虚拟DOM要比真实DOM轻很多
操作对比
假设我们有以下列表:
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
我们现在要将 1、2、3 替换为 4,5,6,7,我们直接操纵节点该如何处理?
- 第一种:我们可以将原列表的1、2、3替换为4、5、6,在新增一个li为7
- 第二种:我们直接把原列表的1、2、3对应的li删掉,在新增4、5、6、7
- 第三中:直接替换 ul的内容,用
innerHTML
直接覆盖
单纯操作来讲,第三种无疑是最方便的,第一种明显复杂一点,但从性能上来讲,第三种的性能最高,因为存在重排与重绘的问题,我们知道浏览器处理DOM
是很慢的,如果页面比较复杂,频繁的操做DOM
会造成很大的开销
。
所以在原生的DOM中我们要想性能高,就只能选择第一种方案,但这样明显给我们带来了复杂度,不利于目前的开发(会在下文详细讲到~)
流程对比
在传统的Web应用中
,数据的变化会实时地更新到用户界面中,于是每次数据微小的变化都会引起DOM
的渲染。
而虚拟DOM的目:是将所有
的操作聚集到一块,计算出所有的变化后,统一更新
一次虚拟DOM
也就是说,一个页面如果有500次变化,没有虚拟DOM的就会渲染500次,而虚拟DOM只需要渲染一次,从这点上来看,页面越复杂,虚拟DOM的优势越大
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-D2aFQ9Xs-1658297236094)(https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/b16d46da6c7a44bfa1b3acfc2595a43b~tplv-k3u1fbpfcp-zoom-in-crop-mark:4536:0:0:0.image?)]
虚拟DOM是什么?
在上面我们说过虚拟DOM
实际上就是对象,接下来详细看看这个对象有什么,栗子🌰:
<div className='Index'>
<div>我是小杜杜</div>
<ul>
<li>React</li>
<li>Vue</li>
</ul>
</div>
转化后:
{
type: 'div',
props: { class: 'Index' },
children: [
{
type: 'div',
children: '我是小杜杜'
},
{
type: 'ul',
children: [
{
type: 'li',
children: 'React'
},
{
type: 'li',
children: 'Vue'
},
]
}
]
}
主要转化为:
- type:实际的标签
- props:标签内部的属性(除
key
和ref
,会形