React教程第二节之虚拟DOM与Diffing算法理解

news/2024/11/20 5:12:48/

1、什么是虚拟DOM

虚拟DOMjavascript的一个对象,是内存中的一种数据结构,以树的形式存储UI的状态,树中的每个节点都代表着真实的DOM,用来描述我们希望在页面看到的 HTML结构;
现在的MVVM 框架,大多使用虚拟DOM进行数据视图的更新,相比较真实DOM的操作,
操作真实DOM时: DOM属性繁多处理增删改成比较繁琐,处理效率低,会出现重绘回流现象,导致页面更新缓缓卡顿;

原生的DOM也是 js的一个对象,只不过是浏览器提供的对象;
比如在JSX 中写法:


const dom = <h1></h1>
// 对应虚拟DOM:
const dom = {type: 'h1'}
const dom = document.createElement('h1')
-------
const dom = <div className="name">Andy</div>
// 对应的虚拟DOM为:
dom = {type: 'div', props:{ className: 'name', children:'Andy'}}

2、虚拟DOM的用途作用

虚拟DOM主要是为了提升操作更新界面的效率;目前前端流行的前端框架React Vue都是使用虚拟DOM进行更新;但是在一些对于性能要求极高画面绘制精细的应用中,虚拟DOM依然无法满足需求,需要使用更加低级的渲染技术,如:WebGL 或者直接操作DOM;

主要流程:

创建虚拟DOM树:将UI组件转化为虚拟DOM树,来表示UI结构;
A、Diffing算法:
每次更新属性状态时候,会新创建一个虚拟DOM树,并与之前的虚拟DOM树进行对比,找出差异;
B、最小范围更新:
通过 Diffing 算法,React 确定需要更新的 DOM 节点,并只对发生变化的部分进行更新;
C、渲染更新:
React 根据 Diffing 结果,对真实 DOM 进行最小化的更新操作。

3、React 通过Diff 算法如何进行 current processworkInProcess 对比的,以及16.8前后版本性能的对比

虚拟DOM的 Diffing 算法是 React优化性能核心,通过启发式算法来对比两颗虚拟的 DOM树,最大限度减少对比的计算量;

同层节点对比
React 只会比较同层的节点,不会跨层对比不同层次的节点。也就是说,如果元素的位置发生了变化,React 会先删除原来的节点,再插入新的节点。

唯一 key 标识:
在处理动态列表时,React 通过 key 属性来区分不同的节点。如果列表中的每个元素都有一个唯一的 key,React 就能高效地找到变化的元素,并只更新该部分。

React 15之前使用的是递归创建虚拟DOM,递归不能中断,如果层级很深,多导致递归线程占用时间长,阻塞主线程而导致出现卡顿现象
React 16之后为了处理这种不能中断的方式,将更新方案修改为异步的可中断方案,推出Fiber架构,将任务切片分隔异步渲染,根据不同的需求分配不同的优先级进行渲染,支持分批次批量更新;
vue2中使用的是双端对比,即:分别一个从头开始,一个从末尾开始,向中间对比靠拢,在递归的同时会对DOM进行操作;

而React认为实际应用中对于列表翻转,大量重绘重排场景比较少,而是采用双缓存的技术,在React的进程中,最多会同时存在两个Fiber树,当前屏幕看到渲染出来的视图树称为 current fiber树;正在缓存中进行状态属性处理的 树称为 workInProcess fiber树,当 workInProcess fiber 树渲染完成后,应用根节点的 current 指针会指向 workInProcess fiber 树,从而将 workInProcess fiber树更改为 current fiber 树完成一次视图更新渲染;

React 的更新会经历两个阶段render 阶段 和 commit 阶段。render 阶段是可中断的,commit 阶段是不可中断的。

render 阶段会生成 fiber 树,所谓的 diff 就会发生在这个阶段。React 通过深度优先遍历来生成 fiber 树,整个过程与递归是类似的,因此生成 fiber 树的过程又可以分为「递」阶段和「归」阶段

commit 阶段主要执行各种 DOM 操作、生命周期钩子、某些 hook 等

因此,diff 阶段不会直接变更 DOM,而是留到 commit 阶段再做变更

4、虚拟DOM 对比时候的 注意事项,key?

如果列表只是简单的展示,没有增删改查操作,可以使用index作为key值,相反则key值需要是唯一的,否则会使新旧DOM对比时候消耗更多的性能;
如图:key 唯一时候,key 使用index 时候图像对比

使用index 作为key 时候如下图:

index 作为key时

使用 唯一标识 作为key 时候

请添加图片描述

``


http://www.ppmy.cn/news/1548416.html

相关文章

CSM32RV20:RISC-V核的低功耗MCU芯片,常用在智能门锁上

CSM32RV20是一款基于RISC-V核的低功耗MCU芯片。 内置RISC-V RV32IMAC内核&#xff08;2.6CoreMark/MHz&#xff09;&#xff1b; 蕞高32MHz工作频率&#xff1b; 内置4kB的SRAM&#xff1b; 内置8B的ALWAYS寄存器&#xff0c;能在掉电模式2下保存数据&#xff1b; 内置40kB的嵌…

区块链中的wasm合约是什么?

概述 让我们梳理一下WASM合约的概念和重要性…这涉及到区块链和智能合约的发展。 WASM(WebAssembly)本身是一种低级的类汇编语言&#xff0c;最初是为Web浏览器设计的。将它引入区块链领域是一个重要创新。 相比传统的智能合约(如Solidity)&#xff0c;WASM有很多优势&#…

stm32启动过程解析startup启动文件

1.STM32的启动过程模式 1.1 根据boot引脚决定三种启动模式 复位后&#xff0c;在 SYSCLK 的第四个上升沿锁存 BOOT 引脚的值。BOOT0 为专用引脚&#xff0c;而 BOOT1 则与 GPIO 引脚共用。一旦完成对 BOOT1 的采样&#xff0c;相应 GPIO 引脚即进入空闲状态&#xff0c;可用于…

泷羽sec-安全见闻(9)

安全见闻&#xff08;9&#xff09; 声明&#xff01; 学习视频来自B站up主 泷羽sec 有兴趣的师傅可以关注一下&#xff0c;如涉及侵权马上删除文章&#xff0c;笔记只是方便各位师傅的学习和探讨&#xff0c;文章所提到的网站以及内容&#xff0c;只做学习交流&#xff0c;其…

【Python】selenium安装+Microsoft Edge驱动器下载配置流程

文章目录 简介一、安装浏览器对应驱动1.1 查看浏览器当前版本1.2 下载驱动器1.3 配置环境1.3.1 补充——忘记python的解释器位置&#xff1f; 二、selenium安装及验证配置1.安装selenium2.验证配置2.2.1 补充——selenium打开浏览器自动退出&#xff1f; 总结 简介 本文主要介…

vue2父传子,子传父通信

在Vue 2中&#xff0c;父子组件之间的通信可以通过props和$emit来实现。 父传子&#xff1a; 在父组件中绑定要传递的数据到子组件的属性上。 在子组件中通过props选项声明接收的属性。 子传父&#xff1a; 在子组件中使用$emit方法触发一个事件&#xff0c;并传递数据。 …

设计模式-Adapter(适配器模式)GO语言版本

前言 个人感觉Adapter模式核心就在于接口之间的转换。将已有的一些接口转换成其他接口形式。并且一般用于对象上&#xff0c;而不是系统上 问题 就用一个简单的问题&#xff0c;懂数据结构的同学可能知道双端队列。那么就用双端队列实现一个栈&#xff08;stack&#xff09;或…

vue 获取摄像头拍照,并旋转、裁剪生成新的图片

描述&#xff1a; vue项目中&#xff0c;获取摄像头进行拍照&#xff0c;并对拍摄的图片进行旋转、裁剪等处理 html部分 <!-- 摄像头列表 --> <el-select v-model"autoVal" size"small" change"change(auto, true)"><el-option…