React原理 - React Virtual DOM 原理

目录

扩展学习资料

 Virtual DOM 是什么【虚拟dom】

React渲染

Virtual DOM VS 原生DOM【vDom是否比原生Dom更高效】

Virtual DOM数据结构

Virtaual DOM Diff【虚拟dom前后比对,更新不同dom的算法】

源码解读

react源码组织方式:

React Stack Reconciler【react 栈 协调】

react v15.6.2 源码

练习


扩展学习资料

名称

链接

备注

Virtual DOM 定义

Virtual DOM and Internals – React

英文

Virtual DOM Node

Mithril.js

英文

VDom与 DOM 的区别

The difference between Virtual DOM and DOM - React Kung Fu

英文

React性能优化:Virtual Dom原理浅析

[译] React性能优化:Virtual Dom原理浅析 - 掘金

[译] Virtual Dom 和 Diff 算法

[译] Virtual Dom 和 Diff 算法在 React 中是如何工作的? - 掘金

  • 比较前一个的内部实例与下一个内部实例
  • 更新内部实例Virtual DOM(JavaScript对象) 中的组件树结构。
  • 仅更新存在实际变化的节点及其子节点的真实DOM。

 Virtual DOM 是什么【虚拟dom】

虚拟DOM(virtualdom,VDOM)是一个编程概念,将UI的“虚拟”表示形式保存在内存中,并通过ReactDOM之类的库渲染成“真实”的DOM,这个过程叫做协调。

virtual dom将UI节点抽象成js对象

UI节点抽象:Virtual Dom对HTML Dom的抽象

Learn Once,Write Anywhere:因为提供了对HTML DOM的抽象,所以在Web开发中,通常不需要去调用DOM API。也是因为抽象,所以React也可以开发Native(React Native)。【跨平台性】

Virtual Dom构建UI

构建UI:以我们经常见的Web开发为例,来看下React是怎么通过Virtual DOM渲染成HTML元素的。

React渲染

class App extends Component {state = {text: 'Virtual DOM',    }render() {const {text} = this.state;render (<div>{text}</div>        )    }
}

通过Virtual DOM 渲染页面

很简单的例子,渲染state遍历text的值。

可以看到React是通过render方法渲染Virtual DOM(这里不考虑优化),从而绘制出真实DOM。意味着,每次修改了state的值就会执行render方法。

Virtual DOM是HTML DOM的映射,基本结构大致是一样的

 

Virtual DOM VS 原生DOM【vDom是否比原生Dom更高效】

  • 原生DOM更新
    • DOM API 调用更新UI
  • Virtual DOM更新
    • 每次render都会产生一份新的‘react dom’
    • Virtual DOM要对新旧‘react dom’进行比较,从而确定在旧‘dom’的基础上进行多少变更
    • 确定最优的变更策略之后调用DOM API更新UI

Virtual DOM渲染成HTML,在流程上会比原生DOM操作多几个步骤

实际应用中,页面的操作逻辑会比较复杂频繁,多次频繁操作Dom会导致页面重绘,页面重绘是影响页面性能的关键指标,造成卡顿。react在内部已经做了考虑,所以说会比原生Dom更加高效

Virtual DOM数据结构

对UI节点抽象

在Virtual DOM中,对HTML节点进行抽象。用JS对象的形式表示HTML。

改变了过去对HTML节点的理解。

呈现在用户面前的页面就是一个复杂的递归对象。

const globaldom = {tagName: 'html',children: [{tagName: 'head',        }, {tagName: 'body',children: [{tagName: 'div',attributes: {className: 'test'               }            }]        }    ]
}

Virtaual DOM Diff【虚拟dom前后比对,更新不同dom的算法】

  • Virtual DOM如何提高性能【高效更新】
  1. 我们将render产生的Virtual DOM简称‘Vdom’;
  2. 通常调用setState方法触发Vdom更新;
  3. 通过对比新旧‘Vdom’,确定最优实现新‘Vdom’所需的操作;
  • Virtual DOM Diff 的层次
    • 组件级别比较
    • 元素级别比较

HTML DOM是个完整的树,常规树遍历的时间复杂度是n³,正是vdom对HTMLdom节点层次的划分,使得HTML树在Vdom中遍历的时间复杂度降为n0这也是Vdom高效的原因之一。

Virtual DOM Diff是体现其性能/维护性的重要过程

  • Component Diff【组件级比较】:不同就直接开始替换组件及它的子组件(不再比对子组件)

 

  • 元素级别的比较【三个层面:创建、移动、删除】

  • 创建子节点

 react源码:diff 添加子节点

createChild: function (child, afterNode, mountImage) {return makeInsertMarkup(mountImage, afterNode, child._mountIndex);
},
  • 删除子节点

 react源码:diff删除子节点

removeChild: function (child, node) {return makeRenove(child, node);
},
  • 移动节点

 react源码:diff移动子节点【截取片段】

// 老节点和新节点相等,说明是移动
if(prevChild === nextChild) {updates = enqueue(updates, this.moveChild(prevChild, lastPlacedNode, nextIndex, lastIndex));lastIndex = Math.max(prevChild._mountIndex, lastIndex);prevChild._mountIndex = nextIndex;
}
moveChild: function (child, afterNode, toIndex, lastIndex) {// 原节点所在的挂载顺序数 < 更新后所在的顺序数if (child._mountIndex < lastIndex) {return makeMove(child, afterNode, toIndex);    } else {// 不移动它,而是把它后面应该在前面的节点移动到它前面去    }
}

我们应该规避如图示例,将最后一个节点移动到最前面。【这种操作显得不那么高效】

react源码比较复杂,不直观【相对开发来说】;

react的移动、创建、删除并不是在react包中实现的,而是在react dom这个包中实现的。【动态挂载技术】

 

源码解读

react源码组织方式:

  1. 动态注入:react包源码中只是声明变量并没有实现,实现是写在react dom包中【考虑到多平台,把公共部分react抽了出来,react dom是个render器; react native是另一个render器;如公共方法setState,react中就只是定义;实现是在react dom、react native中实现各自的。】
  2. react dom中源码:比如渲染HTML节点的时候,采用的是嵌套循环【渲染、更新、比较】(因为HTML树本身就是一种循环嵌套的方式)

React Stack Reconciler【react 栈 协调】

render -> Virtual DOM Diff->commit【更新】

总结

1.Virtual DOM不仅仅是抽象了HTML Dom操作,更多的是抽象了UI节点,其次带来一种编程理念:数据驱动视图。

Virtual DOM本身的抽象性也使得跨平台成为了可能。

2.如何看待VDom比原生Dom更加高效?

(1)高效的Diff算法实现更新

(2)可维护性和编程思维方面

react v15.6.2 源码

react v15.6.2.zip

练习

阅读React源码  React v15.6.2 重点阅读 react-dom ReactMultiChild.js(react-dom/lib/ReactMultiChild.js) 源码。

产出:

  • 一份 Virtual DOM 与 HTML DOM 的对比图;
  • 一份分析 Element 比较的流程图。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/81360.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java八股文面试[JVM]——JVM内存结构

参考&#xff1a; JVM学习笔记&#xff08;一&#xff09;_卷心菜不卷Iris的博客-CSDN博客 JVM是运行在操作系统之上的&#xff0c;它与硬件没有直接的交互 JVM内存结构&#xff1a; 方法区&#xff1a;存储已被虚拟机加载的类元数据信息(元空间) 堆&#xff1a;存放对象实…

鲁图中大许少辉博士八一新书《乡村振兴战略下传统村落文化旅游设计》山东省图书馆典藏

鲁图中大许少辉博士八一新书《乡村振兴战略下传统村落文化旅游设计》山东省图书馆典藏

SQL注入之HTTP头部注入

文章目录 cookie注入练习获取数据库名称获取版本号 base64注入练习获取数据库名称获取版本号 user-agent注入练习获取数据库名称获取版本号 cookie注入练习 向服务器传参三大基本方法:GPC GET方法&#xff0c;参数在URL中 POST&#xff0c;参数在body中 COOKIE&#xff0c;参数…

ssl卸载原理

SSL卸载&#xff0c;也称为SSL解密&#xff0c;是一种将SSL加密数据流卸成非加密的明文数据流的过程。SSL卸载通常在负载均衡器、代理服务器、WAF等设备中实现&#xff0c;可以提高传输效率和安全性。 SSL卸载的原理是将SSL数据流拦截下来&#xff0c;通过设备内置的证书进行解…

MyBatis进阶:告别SQL注入!MyBatis分页与特殊字符的正确使用方式

目录 引言 一、使用正确的方式实现分页 1.1.什么是分页 1.2.MyBatis中的分页实现方式 1.3.避免SQL注入的技巧 二、特殊字符的正确使用方式 2.1.什么是特殊字符 2.2.特殊字符在SQL查询中的作用 2.3.如何避免特殊字符引起的问题 2.3.1.使用CDATA区段 2.3.2.使用实体引…

BDA初级分析——可视化基础

一、可视化的作用 数据可视化——利用各种图形方式更加直观地呈现数据的过程 可视化的作用 1、更快地理解数据&#xff0c;找出数据的规律和异常 2、讲出数据背后的故事&#xff0c;辅助做出业务决策 3、给非专业人士提供数据探索的能力 数据分析问题如何通过可视化呈现&am…

使用css实现点击切换active效果

不使用js&#xff0c;纯css实现点击切换active样式 一个父盒子中嵌套小标签,横向排列 html <div class"box"><a href"#">选项1</a><a href"#">选项2</a><a href"#">选项3</a><a href&…

Bootstrap的类container与类container-fluid有什么区别?

阅读本文前建议先阅读下面两篇博文&#xff1a; 怎么样通过Bootstrap已经编译好(压缩好)的源码去查看符合阅读习惯的源码【通过Source Map(源映射)文件实现】 在CSS中&#xff0c;盒模型中的padding、border、margin是什么意思&#xff1f; 以下是Bootstrap的类 container 的盒…

vue离线缓存资源文件

本文章主要是解决大文件,实时请求资源浪费网络资源的问题 从而有效的将解决用户体验的问题 话不多说上才艺 ⬇️⬇️⬇️⬇️⬇️⬇️⬇️ 找到项目中的 index.html 文件,并在 html 标签中加入 manifest"manifest.appcache" 安装 appcache-manifest 包 npm ins…

Maven 一键部署到 SSH 服务器

简介 利用 Maven Mojo 功能一键部署 jar 包或 war 包到远程服务器上。 配置 在 maven 的setting.xml 配置服务器 SSH 账号密码。虽然可以在工程的 pom.xml 直接配置&#xff0c;但那样不太安全。 <servers><server><id>iq</id><configuration&…

5、Spring_DI注解开发

DI 注解开发 1.目前面临问题 建立 mapper public interface EmployeeMapper {void save(); }建立 mapper 实现类 Repository public class EmployeeMapperImpl implements EmployeeMapper {public void save(){System.out.println("保存员工信息");} }建立 service …

人机对抗智能-部分可观测异步智能体协同(POAC)

环境链接&#xff1a;数据中心-人机对抗智能 (ia.ac.cn)http://turingai.ia.ac.cn/data_center/show/10 1.环境配置 Ubuntu 20.04 Anaconda python版本3.6 1.1 安装torch0.4.1失败 参考文章&#xff1a; 安装torch0.4.1的神坑_torch0.4.1_DEMO_Tian的博客-CSDN博客 co…