• 老生常谈React的diff算法原理-面试版


    第一次发文章 not only(虽然)版式可能有点烂 but also (但是)最后赋有手稿研究 finally看完他你有收获

    diff算法:对于update的组件,他会将当前组件与该组件在上次更新是对应的Fiber节点比较,将比较的结果生成新的Fiber节点。

    ! 为了防止概念混淆,强调

    一个DOM节点,在某一时刻最多会有4个节点和他相关。

    - 1.current Fiber。如果该DOM节点已在页面中,current Fiber代表该DOM节点对应的Fiber节点。
    - 2.workInProgress Fiber。如果该DOM节点将在本次更新中渲染到页面中,workInProgress Fiber代表该DOM节点对应的Fiber节点。
    - 3.DOM节点本身。
    - 4.JSX对象。即ClassComponent的render方法的返回结果,或者FunctionComponent的调用结果,JSX对象中包含描述DOM节点信息。
    
    • 1
    • 2
    • 3
    • 4
    diff算法的本质上是对比1和4,生成2。
    
    • 1
    Diff的瓶颈以及React如何应对
    由于diff操作本身也会带来性能损耗,React文档中提到,即使在最前沿的算法中
    将前后两棵树完全比对的算法的复杂程度为 O(n 3 ),其中 n 是树中元素的数量。
    
    如果在React中使用了该算法,那么展示1000个元素所需要执行的计算量将在十亿的量级范围。
    这个开销实在是太过高昂。
    
    • 1
    • 2
    • 3
    • 4
    • 5

    所以为了降低算法复杂度,React的diff会预设3个限制:

     1.同级元素进行Diff。如果一个DOM节点在前后两次更新中跨越了层级,那么React不会尝试复用他。
     2.不同类型的元素会产生出不同的树。如果元素由div变为p,React会销毁div及其子孙节点,并新建p及其子孙节点。
     3.者可以通过 key prop来暗示哪些子元素在不同的渲染下能保持稳定。
    
    • 1
    • 2
    • 3

    那么我们接下来看一下Diff是如何实现的

    参考 前端react面试题详细解答

    我们可以从同级的节点数量将Diff分为两类:

     1.当newChild类型为object、numberstring,代表同级只有一个节点
    - 2.当newChild类型为Array,同级有多个节点
    
    • 1
    • 2

    单节点diff

    以类型Object为例,会进入这个函数reconcileSingleElement
    
    • 1

    这个函数会做如下事情:
    
    • 1

    让我们看看第二步判断DOM节点是否可以复用是如何实现的。
    
    • 1

    从代码可以看出,React通过先判断key是否相同,如果key相同则判断type是否相同,只有都相同时一个DOM节点才能复用。

    这里有个细节需要关注下:

    1.当child !== null且key相同且type不同时执行deleteRemainingChildren将child及其兄弟fiber都标记删除。
    
    2.当child !== null且key不同时仅将child标记删除。
    
    • 1
    • 2
    • 3

    例子:当

  • 相关阅读:
    从零开始学习Netty - 学习笔记 -Netty入门-ChannelFuture
    还在调API写所谓的AI“女友”,唠了唠了,教你基于python咱们“new”一个(深度学习)
    module ‘numpy‘ has no attribute ‘object‘
    【Vue.js】使用ElementUI搭建动态树&数据表格与分页
    Netty服务端开发及性能优化
    [HDLBits] Count15
    命令模式(command)
    ISP Pipeline典型场景要点SAT、Bokeh、MFNR、HDR
    【LeetCode:689. 三个无重叠子数组的最大和 | 序列dp+前缀和】
    《网络编程从入门到入魔》(建议收藏)
  • 原文地址:https://blog.csdn.net/beifeng11996/article/details/127781613