美文网首页
面试官:说说react的渲染过程

面试官:说说react的渲染过程

作者: 全栈潇晨 | 来源:发表于2021-12-15 07:49 被阅读0次

    面试官:说说react的渲染过程

    hello,这里是潇晨,大家在面试的过程中有没有遇到过一些和react相关的问题呢,比如面试官让你说说react渲染的过程,这到题目比较开放,也比较考验大家对react渲染原理以及源码的整体架构的理解。

    1. 整体流程:

      react源码3.1

      react的核心可以用ui=fn(state)来表示,更详细可以用

      const state = reconcile(update);
      const UI = commit(state);
      

      上面的fn可以分为如下一个部分:

      • Scheduler(调度器): 排序优先级,让优先级高的任务先进行reconcile
      • Reconciler(协调器): 找出哪些节点发生了改变,并打上不同的Flags(旧版本react叫Tag)
      • Renderer(渲染器): 将Reconciler中打好标签的节点渲染到视图上

      那这些模块是怎么配合工作的呢

      • 首先jsx经过babel的ast词法解析之后编程React.createElement,React.createElement函数执行之后就是jsx对象,也被称为virtual-dom。
      • 不管是在首次渲染还是更新状态的时候,这些渲染的任务都会经过Scheduler的调度,Scheduler会根据任务的优先级来决定将哪些任务优先进入render阶段,比如用户触发的更新优先级非常高,如果当前正在进行一个比较耗时的任务,则这个任务就会被用户触发的更新打断,在Scheduler中初始化任务的时候会计算一个过期时间,不同类型的任务过期时间不同,优先级越高的任务,过期时间越短,优先级越低的任务,过期时间越长。在最新的Lane模型中,则可以更加细粒度的根据二进制1的位置,来决定任务的优先级,通过二进制的融合和相交,判断任务的优先级是否足够在此次render的渲染。Scheduler会分配一个时间片给需要渲染的任务,如果是一个非常耗时的任务,如果在一个时间片之内没有执行完成,则会从当前渲染到的Fiber节点暂停计算,让出执行权给浏览器,在之后浏览器空闲的时候从之前暂停的那个Fiber节点继续后面的计算,这个计算的过程就是计算Fiber的差异,并标记副作用。详细可阅读往期课件和视频讲解,往期文章在底部。
      • 在render阶段:render阶段的主角是Reconciler,在mount阶段和update阶段,它会比较jsx和当前Fiber节点的差异(diff算法指的就是这个比较的过程),将带有副作用的Fiber节点标记出来,这些副作用有Placement(插入)、Update(更新)、Deletetion(删除)等,而这些带有副作用Fiber节点会加入一条EffectList中,在commit阶段就会遍历这条EffectList,处理相应的副作用,并且应用到真实节点上。而Scheduler和Reconciler都是在内存中工作的,所以他们不影响最后的呈现。
      • 在commit阶段:会遍历EffectList,处理相应的生命周期,将这些副作用应用到真实节点,这个过程会对应不同的渲染器,在浏览器的环境中就是react-dom,在canvas或者svg中就是reac-art等。

      另外我们也可以从首次渲染和更新的时候看在render和commit这两个子阶段是如果工作的:

      • mount时:
        1. render阶段会根据jsx对象构建新的workInProgressFiber树,不太了解Fiber双缓存的可以查看往期文章 Fiber架构,然后将相应的fiber节点标记为Placement,表示这个fiber节点需要被插入到dom树中,然后会这些带有副作用的fiber节点加入一条叫做Effect List的链表中。
        2. commit阶段会遍历render阶段形成的Effect List,执行链表上相应fiber节点的副作用,比如Placement插入,或者执行PassiveuseEffect的副作用)。将这些副作用应用到真实节点上
      • update时:
        1. render阶段会根据最新状态的jsx对象对比current Fiber,再构建新的workInProgressFiber树,这个对比的过程就是diff算法,diff算法又分成单节点的对比和多节点的对比,不太清楚的同学参见之前的文章 diff算法 ,对比的过程中同样会经历收集副作用的过程,也就是将对比出来的差异标记出来,加入Effect List中,这些对比出来的副作用例如:Placement(插入)、Update(更新)、Deletion(删除)等。
        2. commit阶段同样会遍历Effect List,将这些fiber节点上的副作用应用到真实节点上
      react源码3.2

    视频讲解(高效学习):点击学习

    往期react源码解析文章:

    1.开篇介绍和面试题

    2.react的设计理念

    3.react源码架构

    4.源码目录结构和调试

    5.jsx&核心api

    6.legacy和concurrent模式入口函数

    7.Fiber架构

    8.render阶段

    9.diff算法

    10.commit阶段

    11.生命周期

    12.状态更新流程

    13.hooks源码

    14.手写hooks

    15.scheduler&Lane

    16.concurrent模式

    17.context

    18事件系统

    19.手写迷你版react

    20.总结&第一章的面试题解答

    相关文章

      网友评论

          本文标题:面试官:说说react的渲染过程

          本文链接:https://www.haomeiwen.com/subject/rmrefrtx.html