React源码(自顶向下学习)

261 阅读3分钟

第一章:理念篇

设计理念

  • 设计理念:快速响应

  • 突破瓶颈:

    1. cpu
    2. I/O
  • 解决方案:异步可中断更新


架构的演进史

老的React架构(React15架构)

React15架构可以分为两层

  • Reconciler(协调器)—— 负责找出变化的组件
  • Renderer(渲染器)—— 负责将变化的组件渲染到页面上
  1. Reaconciler(协调器)
    • 每当有更新发生的时候,Reconciler会做以下工作:
      • 调用函数组件、或class组件的render方法,将返回的JSX转化为虚拟DOM
      • 将虚拟DOM和上次更新时的虚拟DOM对比
      • 通过对比找出本次更新中变化的虚拟DOM
      • 通知Renderer将变化的虚拟DOM渲染到页面上
  2. Renderer(渲染器)
    • 浏览器环境渲染的Renderer——ReactDOM
    • ReactNative渲染器,渲染APP原生组件
    • ReactTest渲染器,渲染出纯Js对象用于测试
    • ReactArt渲染器,渲染到Canvas、SVG或VML(IE8)

React15架构的缺点

  • Reconciler中,mount的组件会调用mountComponentupdate的组件会调用updateComponent。这两个方法都会递归更新子组件。

递归更新的缺点

  • 由于递归执行,所以更新一旦开始,中途无法中断。当层级很深时,递归更新超过了16ms,用户交互就会卡顿。

举个例子:

+ 页面同时更新1,2,3
+ +1
+ 第一次点击,后`Reconciler`协调器发现1要变为2,此时通知`Renderer`更新DOM,1变为2
+ 依次执行
+ 问题发生,当此时1,2,3未全部更新完毕,发生异步中断更新,
+ 页面会看到数据更新为2,2,3
> 因此,React,重写架构。

新的React架构(React16架构)

React16架构可以分为三层

  • Scheduler(调度器)—— 调度任务的优先级,高级任务先进入Reconciler
  • Reconciler(协调器)
  • Renderer(渲染器)

与React15架构相比,React16新增了Reconciler(调度器)。

反观例子

  • Scheduler运行
    • 点击button,产生一个更新,更新内容1 --> 2
    • Scheduler,接收到更新,看一下是否有更高优先级的更新需要先执行?
    • 若无,将1-->2 交给Reconciler
  • Reconciler运行
    • 接收到更新,看下造成了哪些虚拟DOM的更新
    • 将1,2,3,全部打上update标记
    • 无其他变化,将打上标记的虚拟DOM交给Renderer
  • Renderer运行
    • 接收到通知,看下哪些被打了标记的虚拟DOM
    • 有三个打了标记,进行更新DOM的操作
  • SchedulerReconciler的运行,可以被中断:
    1. 有没有其他更高优先级的任务需要更新
    2. 当前帧没有剩余时间
  • 由于红框中的工作都在内存中进行,不会更新页面上的DOM,所以即使反复中断,用户也不会看见更新不完全的DOM

Reconciler内部采用了Fiber的架构。

Fiber架构与代数效应的关系

  • 代数效应:将副作用从函数调用逻辑中分离
  • async await, 具有传染性,破坏了同步特性
  • try catch 执行完 栈中被销毁
  • react 与 代数效应 的区别:hooks:不关系数据存储,只关心更新
  • fiber思想就是一种 异步可中断更新
  • 中断、恢复的思想
  • 这是 fiber 纤程
  • generator,
    • 与 async await一致,有传染性
    • 更新可中断并继续、更新有不同优先级,高优先级可以打断低优先级(达不到)