React原理 - React Virtual DOM 原理

这篇具有很好参考价值的文章主要介绍了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的映射,基本结构大致是一样的

React原理 - React Virtual DOM 原理,React相关,react.js,javascript,ecmascript

 

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原理 - React Virtual DOM 原理,React相关,react.js,javascript,ecmascript 

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

React原理 - React Virtual DOM 原理,React相关,react.js,javascript,ecmascript

  • 创建子节点

React原理 - React Virtual DOM 原理,React相关,react.js,javascript,ecmascript

 react源码:diff 添加子节点

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

React原理 - React Virtual DOM 原理,React相关,react.js,javascript,ecmascript

 react源码:diff删除子节点

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

React原理 - React Virtual DOM 原理,React相关,react.js,javascript,ecmascript

 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源码  React v15.6.2 重点阅读 react-dom ReactMultiChild.js(react-dom/lib/ReactMultiChild.js) 源码。

产出:文章来源地址https://www.toymoban.com/news/detail-677635.html

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

到了这里,关于React原理 - React Virtual DOM 原理的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Node.js npm V8 React Express的运行配合关系:构建JavaScript应用的基石

    目录 Node.js 和 V8 引擎 Node.js 和 npm LTS(Long Term Support) React Node.js的作用 Express Node.js 和 V8 引擎 Node.js 使用 Google 的 V8 JavaScript 引擎 来执行 JavaScript 代码。V8 是一个高性能的 JavaScript 和 WebAssembly 引擎,用于在 Google Chrome 浏览器和 Node.js 中运行 JavaScript。 V8 引擎的更新 通常包括

    2024年03月12日
    浏览(64)
  • React 路由react-router-dom详解

    前面我们先了解一下 路由是什么? 路由分类有哪些?内置API有哪些 ? 可能有点枯燥,不喜欢看的直接跳过 ! 单页Web应用(single page web application,SPA)。 整个应用只有一个完整的页面。 点击页面中的链接不会刷新页面,只会做页面的局部更新。 数据都需要通过ajax请求获取

    2023年04月11日
    浏览(41)
  • 面试题-React(二):React中的虚拟DOM是什么?

    一、什么是虚拟DOM? 虚拟DOM是React的核心概念之一,它是一个轻量级的JavaScript对象树,用于表示真实DOM的状态。在React中,当数据发生变化时,首先会在虚拟DOM上执行DOM更新,而不是直接操作真实DOM。然后,通过比较前后两个虚拟DOM的差异,最小化真实DOM的操作,从而减少页

    2024年02月12日
    浏览(49)
  • 前端react入门day03-react获取dom与组件通信

    (创作不易,感谢有你,你的支持,就是我前行的最大动力,如果看完对你有帮助,请留下您的足迹) 目录 受控表单绑定  React中获取DOM 组件通信 父传子  父传子-基础实现 父传子-props说明 父传子 - 特殊的prop children 子传父  使用状态提升实现兄弟组件通信 使用Context机制跨

    2024年02月01日
    浏览(54)
  • React07-路由管理器react-router-dom(v6)

    react-router 是一个流行的用于 React 应用程序路由的库。它使我们能够轻松定义应用程序的路由,并将它们映射到特定的组件,这样可以很容易地创建复杂的单页面应用,并管理应用程序的不同视图。 react-router 是基于 React 构建的,因此与其他 React 库和工具集成得很好。它在许

    2024年02月02日
    浏览(42)
  • React基础入门之虚拟Dom

    React官方文档: https://react.docschina.org/ 重要提示:本系列文章基础篇总结自尚硅谷课程,且采用类式写法!!最新的函数式组件写法见高级篇。 本系列文档旨在帮助vue同学更快速的学习react,如果你很熟悉vue,且想更好地了解react,建议从 类式组件 学起! 学习本教程之前,最

    2024年02月11日
    浏览(52)
  • 面试题:React的真实DOM和虚拟DOM的区别

    真实DOM,就是文档对象类型,在页面上渲染的每一个节点都是一个真实DOM结构。 虚拟DOM,就是一个描述描述DOM结构的对象。 在创建虚拟DOM的目的就是为了更好将虚拟节点渲染到页面上,虚拟DOM对象的节点与真实DOM的属性是一一对应的。 在React中,ReactDOM.render()函数将虚拟DO

    2024年04月09日
    浏览(50)
  • React 18 使用 ref 操作 DOM

    参考文章 由于 React 会自动处理更新 DOM 以匹配渲染输出,因此在组件中通常不需要操作 DOM。但是,有时可能需要访问由 React 管理的 DOM 元素 —— 例如,让一个节点获得焦点、滚动它或测量它的尺寸和位置。在 React 中没有内置的方法来做这些事情,所以需要一个指向 DOM 节点

    2024年02月10日
    浏览(40)
  • 【React学习】—虚拟DOM两种创建方式(二)

    使用jsx创建虚拟DOM 使用js创建虚拟DOM 本质是Object类型的对象(一般对象) 虚拟DOM比较轻,真实DOM比较重,因为虚拟DOM是React内部在用 虚拟DOM最终会被React转化为真实DOM,呈现在页面上

    2024年02月14日
    浏览(54)
  • 277/300 React+react-router-dom+Vite 二级页面刷新时,白屏问题解决

    BrowserRouter 换为 HashRouter

    2024年02月13日
    浏览(49)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包