本文内容全部来源于卡颂大佬的React技术揭秘及其配套视频自顶向下学React源码
React技术揭秘-理念篇总结
React是什么?
- React是用于构建用户界面的JavaScript库,简单来说是一个ui库,用一个函数公式表示为:
fn(props)-> UI
. - React的核心思路:
- 声明式: 代码直观,便于组合
- 组件化: 视图拆分,模块复用,降低耦合
- 通用性: 一次学习,随处编写,比如RN
- React的设计理念: 快速响应 但是 快速响应会受到一些因素影响,比如:
- 大量计算导致的cpu内存不足(CPU)
- 网络请求(IO)
如何解决这些制约? -- React16 采用了
异步可中断更新
来解决这些制约.
React架构演进史(对比15和16版本)
- React15版本架构
- Reconciler协调器,diff找出组件变化,因为基于递归,数据保存在递归调用栈,被称为 Stack Reconciler
- 调用函数组件或者类组件的render方法, 将jsx转化成虚拟dom
- 将虚拟dom和上次更新的虚拟dom对比
- 通过对比找出本地更新中变化的虚拟dom
- 通知Renderer渲染器,将变化的虚拟dom渲染到页面
缺点: 采用的递归更新,无法中断,组件层级很深时,更新时间有可能会超过16ms(1000ms/60hz)
- Renderer渲染器:将变化的组件更新到页面
- React16架构
Scheduler调度器
: 调度任务的优先级,高优先级任务优先进入ReconcilerReconciler协调器
: 负责找出变化的组件Renderer渲染器
: 负责将变化的组件渲染到页面上
- React16为何要重写Stack Reconciler 为fiber Reconciler?
React15的架构在对于每一个组件Reconciler和Renderer是依次执行工作,但是由于整个更新流程的过程是同步的,所以视图上,所有更新是会同时改变,若在此基础上 改为异步可中断更新,用户会看到没有更新完整的ui,这对于用户来说是一个BUG.React15架构的缺点
而fiber架构中,由Scheduler调度优先级后,Reconciler协调器对比组件变化,会将变化的组件打上对应的标记,这一过程结束后,才将打上标记的虚拟DOM交给Renderer, Scheduler和Reconciler都是在内存中进行的,不会更新页面DOM,即使反复中断,也不会影响页面,所以react认为老的架构无法实现异步可中断更新
Fiber
- Fiber的设计初衷:
- 更新可以中断,并且可以继续
- 更新可以拥有不同的优先级,高优先级的更新可以打断低优先级的更新
- 什么是Fiber?
作为架构
: 对比于React15的将数据保存在递归调用栈的Stack Reconciler,React16的Reconciler是基于fiber节点
实现的,被称为fiber Reconciler
作为静态数据结构
: 每个fiber节点丢应一个React组件,保存了该组件的类型和对应的dom信息等作为动态工作单元
: 每个fiber节点 保存了本次更新中该组件改变的状态,要执行的工作(需要被删除/被插入/...)
- 什么是双缓存? React16使用双缓存的体现?
在内存中构建并且直接替换的技术叫做双缓存
React使用了 双缓存 来完成fiber树的构建与替换,对应dom树的创建与更新
在React中最多会同时存在两棵树, 对应已经渲染在页面内容的fiber树叫current Fiber
树,正在内存中构建的叫workInProgress Fiber
树,两棵树通过alternate
属性连接
workInProgress Fiber
构建完成在commit阶段渲染到页面,此时React应用的根结点fiberRoot
的current会指向 workInProgress Fiber
,此时的workInProgress Fiber
就变成了current Fiber
树,这就是React使用双缓存技术的体现