React源码学习日记01-理念

203 阅读3分钟

本文内容全部来源于卡颂大佬的React技术揭秘及其配套视频自顶向下学React源码

React技术揭秘-理念篇总结

React是什么?

  1. React是用于构建用户界面的JavaScript库,简单来说是一个ui库,用一个函数公式表示为:fn(props)-> UI.
  2. React的核心思路:
    • 声明式: 代码直观,便于组合
    • 组件化: 视图拆分,模块复用,降低耦合
    • 通用性: 一次学习,随处编写,比如RN
  3. React的设计理念: 快速响应 但是 快速响应会受到一些因素影响,比如:
  • 大量计算导致的cpu内存不足(CPU)
  • 网络请求(IO) 如何解决这些制约? -- React16 采用了 异步可中断更新来解决这些制约.

React架构演进史(对比15和16版本)

  1. React15版本架构
  • Reconciler协调器,diff找出组件变化,因为基于递归,数据保存在递归调用栈,被称为 Stack Reconciler
    • 调用函数组件或者类组件的render方法, 将jsx转化成虚拟dom
    • 将虚拟dom和上次更新的虚拟dom对比
    • 通过对比找出本地更新中变化的虚拟dom
    • 通知Renderer渲染器,将变化的虚拟dom渲染到页面
    • 缺点: 采用的递归更新,无法中断,组件层级很深时,更新时间有可能会超过16ms(1000ms/60hz)
  • Renderer渲染器:将变化的组件更新到页面
  1. React16架构
  • Scheduler调度器: 调度任务的优先级,高优先级任务优先进入Reconciler
  • Reconciler协调器: 负责找出变化的组件
  • Renderer渲染器: 负责将变化的组件渲染到页面上
  1. React16为何要重写Stack Reconciler 为fiber Reconciler?

React15的架构在对于每一个组件Reconciler和Renderer是依次执行工作,但是由于整个更新流程的过程是同步的,所以视图上,所有更新是会同时改变,若在此基础上 改为异步可中断更新,用户会看到没有更新完整的ui,这对于用户来说是一个BUG.React15架构的缺点

而fiber架构中,由Scheduler调度优先级后,Reconciler协调器对比组件变化,会将变化的组件打上对应的标记,这一过程结束后,才将打上标记的虚拟DOM交给Renderer, Scheduler和Reconciler都是在内存中进行的,不会更新页面DOM,即使反复中断,也不会影响页面,所以react认为老的架构无法实现异步可中断更新

Fiber

  1. Fiber的设计初衷:
    • 更新可以中断,并且可以继续
    • 更新可以拥有不同的优先级,高优先级的更新可以打断低优先级的更新
  2. 什么是Fiber?
  • 作为架构: 对比于React15的将数据保存在递归调用栈的Stack Reconciler,React16的Reconciler是基于 fiber节点实现的,被称为fiber Reconciler
  • 作为静态数据结构: 每个fiber节点丢应一个React组件,保存了该组件的类型和对应的dom信息等
  • 作为动态工作单元: 每个fiber节点 保存了本次更新中该组件改变的状态,要执行的工作(需要被删除/被插入/...)
  1. 什么是双缓存? React16使用双缓存的体现? 在内存中构建并且直接替换的技术叫做双缓存

React使用了 双缓存 来完成fiber树的构建与替换,对应dom树的创建与更新

在React中最多会同时存在两棵树, 对应已经渲染在页面内容的fiber树叫current Fiber树,正在内存中构建的叫workInProgress Fiber树,两棵树通过alternate属性连接

workInProgress Fiber构建完成在commit阶段渲染到页面,此时React应用的根结点fiberRoot的current会指向 workInProgress Fiber,此时的workInProgress Fiber就变成了current Fiber树,这就是React使用双缓存技术的体现