iis服务器助手广告广告
返回顶部
首页 > 资讯 > 前端开发 > JavaScript >React的调和算法Diffing算法策略详解
  • 937
分享到

React的调和算法Diffing算法策略详解

2024-04-02 19:04:59 937人浏览 安东尼
摘要

目录算法策略单节点diffing数组节点diffingkey值的使用要求算法策略 React的调和算法,主要发生在render阶段,调和算法并不是一个特定的算法函数,而是指在调和过程

算法策略

React的调和算法,主要发生在render阶段,调和算法并不是一个特定的算法函数,而是指在调和过程中,为提高构建workInProcess树的性能,以及Dom树更新的性能,而采用的一种策略,又称diffing算法。 在React 的官网上描述“Diffing” 算法时,提到了“diffing two trees”,但是在源码实现时,并不是创建好两棵树后,再从上往下的diffing这两棵树。这个diffing发生在搭建子节点时, 实际是新生成的ReactElement 与 current树上fibe节点的diffing。 为了将diffing算法的时间复杂度控制在O(n)(树diff的时间复杂度涉及到树的编辑距离,可以看这里), 采用了如下策略:

只比较同层级的节点,(貌似这一点没有在官网中提到)

对于单节点比较,如果当前节点type 和 key 不相同,不再比较其下子节点,直接删掉该节点及其下整棵子树,根据ReactElement重新生成节点树。因为React认为不同类型的组件生成的树形结构不一样,不必复用。

如果子节点是数组,可根据唯一的key值定位节点进行比较,这样即使子节点顺序发生变化,也可以根据key值进行复用。

值得注意的是,所有节点的diffing都会比较key,key 默认值为null。若是没有设置,则null是恒等于null的,认为key是相同的。

单节点diffing

单个节点进行diffing时,会diffing两组属性:fibe.elementType vs ReactElement.type , fibe.key vs ReactElement.key, 如果这两组属性都相等,数据结构的物理空间会有如下复用逻辑(详见源码reconcileSingleElement函数):

  1. 如果current fibe 存在 alternate 节点,(这意味着这个fibe节点之前参与过调和),则复用该alternate节点的物理空间;否则需要clone current fibe节点,占用新的物理空间
  2. 对应的instance 或者 Dom 会被复用
  3. current fibe 下的child树也会被直接挂载过来(下一步递归子节点时,会被使用)

如果两组属性有一个不相等:

  • fibe 根据ReactElement重新创建
  • 对应的instance和Dom 也会重建
  • child 树全部删除。

如果生成的ReactElement 是单节点,但是对应的current树上是多节点时,会从逐一查找有没有匹配的,找到匹配的,其他的都删除;找不到,全部删除。例如Couter组件有如下逻辑:当点击次数大于10时,隐藏点击按钮。当到达第10次时,span节点会被复用。


class Counter extends React.Component{
    state={
        count:0
    }
    addCount = ()=>{
        const count = this.state.count+1;
        this.setState({count})
    }
    componentDidUpdate(){
        console.log("updated")
    }
    render(){
        return this.state.count < 10 ? [
            <button onClick={this.addCount}>点击</button>
            <span>点击次数:{this.state.count}</span>
        ]:<span>点击次数:{this.state.count}</span>;
    }
}

数组节点diffing

数组节点进行diffing时,流程比较复杂:(源码见reconcileChildrenArray函数)

中间有两次重要的遍历,第一次按index遍历,新旧节点依次比较,遇到key值不匹配的立即中断遍历。 第二次遍历,对剩下的旧节点建立 “key - 节点”的Map表,遍历剩下的新节点,按key值从表中查找旧节点进行比较。以下是三种case下,新旧节点匹配比较的情况。

key值的使用要求

从单节点和数组节点的diffing上看,key值主要是为了减少新建。为了保证diffing时新建旧节点能匹配上,key值使用时有如下注意:

  1. 得稳定,如果key值每次都变化(比如使用了随机数),diffing时,新旧节全部匹配不上,将会引起大量的新建;
  2. 必须得唯一,如果key值不唯一,在建立“key - 节点”的Map表时,会遗漏和错乱,导致页面更新错误。

对于单节点,diffing时key值也会用到,不要认为其没用随便乱设置。 也有一些不规范的用法,对单节点使用key值来实现组件的销毁和重建,但这种用法是不符合React的设计理念的。

例如,有一个日志组件,内部拉取日志数据,对外部没有数据依赖。但是在需求迭代时,在同页面增加了审批操作,审批后,后端会新增一条日志数据,这时候会希望前端页面实时的展示新增的日志数据,会需要触发日志组件重新拉取数据。如果不使用向上提升数据的方式来解决问题,可以给该组件指定一个随机的key,当审批操作完成时,修改key值,则组件就会重新构建。但这种方式的开销较高,整个组件树都会销毁重建。可以采用其他解决方案代替,例如可以给该组件指定ref,当审批完成后,通过ref调用该组件的刷新函数,重新获取数据,更新组件。

对于数组节点,key值主要是在子节点位置发生大的错位时,会起到关键作用。 对于普通的末尾新增,和末尾删除,第一次index遍历就可以匹配完,不会进入第二次key map的遍历。 因为key值对“稳定”和“唯一”性这两个要求,一般前端会需要后端对list数据提供一个唯一标识,对于聚合接口,会给后端增加额外工作,这种情况,可以先了解数据的变化特性,再决定是否真的需要设置key。

对于上面的日志组件,日志是一个列表,新增的日志,都是插在第一行,如果不设置key,基本上所有的子节点都要更新。如果设置key,就需要后端服务为每一条日志增加“永远”惟一的标识符,例如id。曾经经历过一次因为key值的唯一性变化,导致数据更新时页面展示错误的案例。

到此这篇关于React 的调和算法(Diffing 算法)的文章就介绍到这了,更多相关React Diffing 算法内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: React的调和算法Diffing算法策略详解

本文链接: https://www.lsjlt.com/news/161162.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • React的调和算法Diffing算法策略详解
    目录算法策略单节点diffing数组节点diffingkey值的使用要求算法策略 React的调和算法,主要发生在render阶段,调和算法并不是一个特定的算法函数,而是指在调和过程...
    99+
    2024-04-02
  • React中调和算法Diffing算法策略的示例分析
    这篇文章主要为大家展示了“React中调和算法Diffing算法策略的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“React中调和算法Diffing算法策略的示例分析”这篇文章吧。算法...
    99+
    2023-06-22
  • PyTorch策略梯度算法详情
    目录0. 前言1. 策略梯度算法2. 使用策略梯度算法解决CartPole问题0. 前言 本节中,我们使用策略梯度算法解决 CartPole 问题。虽然在这个简单...
    99+
    2024-04-02
  • react中的虚拟dom和diff算法详解
    虚拟DOM的作用 首先我们要知道虚拟dom的出现是为了解决什么问题的,他解决我们平时频繁的直接操作DOM效率低下的问题。那么为什么我们直接操作DOM效率会低下呢? 比如我们创建一个d...
    99+
    2024-04-02
  • React diff算法超详细讲解
    目录diff 算法介绍diff 策略tree diffcomponent diffelement diff结合源码看 diff整体流程新内容为 REACT_ELEMENT_TYPE新...
    99+
    2022-11-13
    React diff算法原理 React diff算法源码
  • 详解react应用中的DOM DIFF算法
    目录前言 什么是Virtual DOM? 使用Virtual DOM的原因 DOM 渲染页面的操作流程 Virtual DOM的优势如何将DOM用virtual DOM 来表...
    99+
    2024-04-02
  • PyTorch策略梯度算法怎么使用
    这篇文章主要介绍“PyTorch策略梯度算法怎么使用”,在日常操作中,相信很多人在PyTorch策略梯度算法怎么使用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”PyTorch策略梯度算法怎么使用”的疑惑有所...
    99+
    2023-07-02
  • 计算机策略无法打开的解决方法是怎样的
    计算机策略无法打开的解决方法是怎样的,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。处理的办法:1. 右键单击“我的电脑”,然后单击“属性”。 2. 在...
    99+
    2023-06-14
  • 如何优化PHP开发中的缓存策略和算法
    缓存是提高Web应用性能的重要手段之一,而在PHP开发中,优化缓存策略和算法则是提高Web应用性能的关键。本文将介绍一些优化PHP开发中的缓存策略和算法的方法,并给出具体的代码示例。一、选择适当的缓存算法在PHP开发中,常见的缓存算法包括最...
    99+
    2023-10-21
    例如使用哈希表
  • Redis删除策略的三种方法及逐出算法
    目录一、前言二、Redis中的数据特征三、时效性数据储存结构四、数据删除策略1、定时删除2、惰性删除3、定期删除五、删除策略对比六、逐出算法1、概念引入2、八种配置一、前言 在文章开...
    99+
    2022-11-13
    Redis删除策略 Redis逐出算法
  • Python编程算法中的存储和同步策略有哪些?
    Python作为一门强大的编程语言,被广泛应用于各种领域,包括算法。在算法编程中,存储和同步策略是非常重要的考虑因素。在本文中,我们将探讨Python编程算法中的存储和同步策略有哪些,并提供一些实用的演示代码。 存储策略 存储策略是指...
    99+
    2023-10-05
    编程算法 同步 存储
  • 数组同步算法:ASP中的技巧和策略是什么?
    在ASP中,数组同步算法是一种常见的技巧,用于将多个数组中的元素同步更新,以保证它们在使用时保持一致性。本文将介绍ASP中数组同步算法的实现技巧和策略,并提供一些演示代码,帮助读者更好地理解和应用这种算法。 一、ASP中的数组同步算法 在...
    99+
    2023-09-19
    数组 同步 编程算法
  • React中的任务调度算法是什么
    这篇文章主要讲解了“React中的任务调度算法是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“React中的任务调度算法是什么”吧!React中的任务池...
    99+
    2024-04-02
  • react diff算法源码解析
    目录单节点Diff reconcileSingleElement多节点Diff reconcileChildrenArray如何判断节点移动了? 总结 React中Diff算法又称为...
    99+
    2024-04-02
  • 【数据结构】-向上调整算法和向下调整算法
    作者:小树苗渴望变成参天大树 作者宣言:认真写好每一篇博客 作者gitee:gitee 如 果 你 喜 欢 作 者 的 文 章 ,就 给 作 者 点 点 关 注 吧! 堆 前言一、堆的...
    99+
    2023-09-17
    数据结构 php 开发语言
  • Vue3diff算法之双端diff算法详解
    目录双端Diff算法双端比较的原理简单Diff的不足双端Diff介绍Diff流程第一次diff第二次diff第三次diff第四次diff双端Diff的优势非理想情况的处理方式添加新元...
    99+
    2024-04-02
  • React中的Diff算法你了解吗
    目录一、Diff算法的作用二、React的Diff算法  1、什么是调和?2、什么是React diff算法?3、diff策略4、tree diff:5、comp...
    99+
    2024-04-02
  • React diff算法面试考点超详细讲解
    目录前言diff算法的概念手写diff算法的过程前言 在前端工程上,日益复杂的今天,性能优化已经成为必不可少的环境。前端需要从每一个细节的问题去优化。那么如何更优,当然与他的如何怎么...
    99+
    2022-12-19
    React diff算法原理 React diff算法源码
  • Java算法真题详解运用单调栈
    目录1.下一个更大元素题目描述思路详解代码与结果2.每日温度题目描述思路详解代码与结果3.下一个更大元素II题目描述思路详解代码与结果1.下一个更大元素 题目描述 思路详解 这一题...
    99+
    2024-04-02
  • Dijkstra算法与Prim算法的异同案例详解
    目录Dijkstra简述Prim简述异同思想时间复杂度Dijkstra特例Dijkstra简述 Dijkstra算法用于构建单源点的最短路径树(MST)——即树中某个点到任何其他点的...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作