「React深入」一文吃透虚拟DOM和diff算法

本文深入探讨了React的虚拟DOM及其与真实DOM的区别,包括结构、操作和流程对比。虚拟DOM的优势在于提高效率和性能,通过diff算法优化DOM操作。文章详细解释了React组件大写的原因、React.Fragment的使用以及虚拟DOM如何转化为真实DOM。同时,介绍了React的diff策略,如tree diff、component diff和element diff,以及如何通过key优化性能。
摘要由CSDN通过智能技术生成

前言

大家好,我是小杜杜,React中的虚拟DOMdiff算法是非常核心的特型,了解它们是非常有必要,只有了解,才能深入。

我们直接来看看以下几个问题:

  • 虚拟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.createElementdocument.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:标签内部的属性(除keyref,会形
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值