自顶而下学习react源码 理念篇

Posted lin-fighting

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了自顶而下学习react源码 理念篇相关的知识,希望对你有一定的参考价值。

理念篇

  • 快速响应的瓶颈之一就是cpu限制,浏览器的js线程与gui渲染线程互斥,一旦js执行过长,就会导致卡顿。

​ 解决这个问题的关键就是:在浏览器每一帧的时间中,预留一些时间给JS线程,React利用这部分时间更新组件

​ 解决CPU瓶颈的关键是实现时间切片,而时间切片的关键是:将同步的更新变为可中断的异步更新。

  • 瓶颈之二就是IO的瓶颈: React实现了[Suspense ]功能及配套的hook——useDeferredValue为了支持这些特性,同样需要将同步的更新变为可中断的异步更新

老的react架构

分为两层:Reconciler(协调器)—— 负责找出变化的组件. Renderer(渲染器)—— 负责将变化的组件渲染到页面上

当有更新变化的时候,Reconclier会调用函数组件或者类组件的render方法,得到虚拟dom,然后进行diff算法比对,将变化的虚拟dom叫个Renderer渲染到页面上。

该架构的缺点:在Reconciler中,mount组件调用mountComponent方法,而update组件调用updateComponent方法,两个方法都会递归更新子组件,一旦开始,无法中断,当层级很深的时候,就会超过16ms,导致卡顿。react15的架构支持中断异步更新吗?

答案是否定的:老的架构,Reconciler和Renderer阶段是交替工作的,当有一处变化的时候,Reconciler比对完变化就立马给到Renderer去渲染,然后再继续寻找变化,如果中途断掉的话,这样就会导致用户可能会看到渲染不完全的ui。

新的react架构

react16的架构分为三层:

  • Scheduler(调度器)—— 调度任务的优先级,高优任务优先进入Reconciler
  • Reconciler(协调器)—— 负责找出变化的组件
  • Renderer(渲染器)—— 负责将变化的组件渲染到页面上
scheduler

react16新增了一个调度器scheduler,因为需要以浏览器是否有剩余时间作为任务中断的标准,需要一种机制,当浏览器有剩余时间的时候通知我们。比如部分浏览器实现的requeistIdleCallback,但是因为浏览器兼容性和触发频率的不稳定性,react实现了功能更加完备的requestIdleCallbackpolyfill,就是S cheduler,除了能在浏览器空闲时出发回调,还可以提供多种任务调度的功能。

Reconciler

react15中·,Reconciler是递归处理虚拟do m的,而react16的Reconciler,从递归变成了可以中断的循环过程,每次循环都会调用shouldYeild判断当前是否有剩余时间,再决定是否继续处理j s。

/** @noinline */
function workLoopConcurrent() 
  // Perform work until Scheduler asks us to yield
  while (workInProgress !== null && !shouldYield()) 
    workInProgress = performUnitOfWork(workInProgress);
  

并且为了解决中断更新渲染不完全的问题,Reconciler和Renderer不再交替工作,而是当Schedule将任务交给Reconciler后,Reconciler处理所有fiber,将变化的fiber打上effectTag标记,只有所有的组件都完成了Reconciler工作,才会统一交给Renderer。

Schedule和Reconciler的工作是在内存中完成的,是可以中断(当前帧没有剩余时间,或者有其他更高优先级任务需要更新)的,用户并没有体验,而Renderer阶段是不可以中断的,如果中断会导致页面渲染不完整。

简而言之,15的Reconciler和Renderer是交替进行的,中断会导致不完全的ui,而react16在所有的组件完成Reconciler阶段,才统一交给R enderer阶段去渲染,所以这中间,Reconciler是可以因为某些原因中断的。

FIber

虚拟Dom无法满足可中断的异步更新需求。Fiber应运而生,作为架构,Recocniler基于Fiber节点实现,称为Fiber Reconciler,而作为静态的数据结构,fiber对应每一个React element,保存了组件的类型,对应的dom信息,相当于对应每一个虚拟dom。作为动态的工作单元,每个fiber节点保存了本次更新中组件的状态。

学习文章地址:https://react.iamkasong.com/

以上是关于自顶而下学习react源码 理念篇的主要内容,如果未能解决你的问题,请参考以下文章

自顶而下学习react源码 架构篇 commit阶段

react源码学习之-理念篇

react源码学习1(理念)

自顶而下系统构架分析

学fpga(先自顶而下设计,再自下而上集成)

如何使用 cocos2d 在自顶向下视图中的精灵下放置阴影