React理念篇

143 阅读3分钟

React设计理念

React 是用 JavaScript 构建快速响应的大型 Web 应用程序的首选方式。

是什么制约了应用的快速响应

  • CUP瓶颈

    操作大量运输时,导致页面卡顿和掉帧率。 浏览器刷新频率是60HZ/s,也就是1s种渲染60帧,16.6ms渲染一帧,在这段时间内,需要做的事情是js执行,然后布局,再绘制。如果js运行时间过长,超过16.6ms,那就没有时间进行布局和绘制了。所以产生掉帧,页面有动画的时候就会比较明显。

  • IO瓶颈

    发送网络请求时,由于要等待请求结果页面才能响应, 因此这个问题是天然存在的。

React做了哪些努力去解决这两个问题

  • CPU瓶颈问题

    采用了时间切片的方式,在一帧中预留部分时间给js线程执行任务,这部分时间执行完后,js还没执行完也会讲控制权还给浏览器(将JS同步更新变更为可中断的异步更新),执行GUI线程,让页面进行布局和绘制,不让页面卡顿掉帧。 React中是进行了架构升级,从15的stack Reconciler, 升级为16的fiber Reconciler, 同时增加了调度器。

  • IO瓶颈问题

    React给出的答案是:将人机交互研究的结果整合到真实的 UI 中。 React中的实现是引入Suspense

React新老架构对比

老架构 15

老架构分为2层:

  • Reconciler(协调器) 负责找出需要变化的组件并标记
  • Renderer(渲染器) 负责将变化的组件渲染出来

Reconciler协调器

当代码中有setState、forceUpdate、ReactDom.render等api执行触发更新时,reconciler执行流程。

  1. 调用组件的render方法,将JSX转为虚拟Dom,(JSX -> React.createElement -> VNode)
  2. 找出本次虚拟DOM和上次虚拟DOM变化的部分 (diff算法)
  3. 交由Renderer将变化的部分渲染

Renderer渲染器

React是跨平台的,不同平台有不同的渲染器, 前端使用的是ReactDom.render.比如还有

  • ReactNative渲染器 APP原生组件
  • ReactTest渲染器 纯js组件用来测试
  • ReactArt 渲染器 渲染成Canvas\SVG

老架构的缺点

老架构的协调器采用的是递归的方法去做diff,这样使得开始后js线程就会一直被占用,不能中断,js执行时间过长就会出现掉帧卡顿, 就是CPU瓶颈。还有React15架构是协调器和渲染器是交替更新的,找到一个diff,就更新一个, 如果更新中途中断了, 则会出现UI错乱(React15不会出现中断更新情况)。

新架构16

新架构分为三层

  • Scheduler(调度器) 调度任务的优先级, 高优先级任务会优先进入协调器recociler.
  • Reconciler(协调器) 负责找出需要变化的组件并标记
  • Renderer(渲染器) 负责将变化的组件渲染出来

Scheduler调度器

调度器有2个功能, 一是设置任务的优先级, 二是可以中断任务,只在浏览器空闲的时候执行任务(浏览器原生requestIdelCallback, 有兼容性, 自己实现了)

Reconciler协调器

与15的协调器相比区别

  • 由递归,变为可中断的循环过程。
function workLoopConcurrent() {
//  workInProgress 待处理的节点
// shouldYield 浏览器是否还有空余时间
  while (workInProgress !== null && !shouldYield()) {
    workInProgress = performUnitOfWork(workInProgress);
  }
}
  • 不再是与renderer交替工作,而是先完成所有diff, 在dom上打上标记, 然后统一交给renderer(渲染器)

Reconciler中引入了一个新的数据结构Fiber, 一个节点对应一个VDOM也对应一个Fiber节点。Fiber节点的引入更加方便的实现了可中断更新。 (理论上VDOM也是可以的, 只是处理上会更复杂)。

Renderer渲染器

Reconciler处理后,就得到了标记过的Fiber树, 根据这些标记,做统一的渲染操作。

学习文档: react.iamkasong.com/