# 结构脉络梳理

# react理念

react理念

我们认为,React 是用 JavaScript 构建快速响应的大型 Web 应用程序的首选方式。 它在 Facebook 和 Instagram 上表现优秀。

我们日常使用App,浏览网页时,有两类场景会制约快速响应:

  • 当遇到大计算量的操作或者设备性能不足使页面掉帧,导致卡顿。

  • 发送网络请求后,由于需要等待数据返回才能进一步操作导致不能快速响应。

这两类场景可以概括为:

1、CPU的瓶颈

时间分片:将同步更新变成可中断的异步更新

一帧的动画是16.6ms, 我们只占用5ms,剩余时间执行样式布局和样式绘制。

2、IO的瓶颈

ios 设置-通用 - 对比 - 设置-siri与搜索

减少网络延迟:将人机交互的研究结果整合到真实的UI中。苹果设置

提前加载suspense/useDeferredValue

function App() {
  const [text, setText] = useState("hello");
  const deferredText = useDeferredValue(text, { timeoutMs: 2000 }); 

  return (
    <div className="App">
      {/* 保持将当前文本传递给 input */}
      <input value={text} onChange={handleChange} />
      ...
      {/* 但在必要时可以将列表“延后” */}
      <MySlowList text={deferredText} />
    </div>
  );
 }

# 新老架构对比

# 15

Reconciler - 协调器 负责找到变化的组件

每当有更新发生时:

  • 调用函数组件、class组件中的render方法,将返回的jsx转换为虚拟的DOM
  • 将虚拟的DOM和上次更新后的DOM做对比
  • 通过对比找到本次需要更新变化的虚拟DOM
  • 通知Renderer将变化的虚拟DOM渲染到页面上。

Render - 渲染器 负责将变化的组件渲染到页面上来

# 15的缺陷

mountComponent/updateComponent 都会递归更新子组件。 由于递归执行,所以一旦开始,中途就无法中断。当层级很深时,递归更新时间超过了16ms,用户交互就会很卡。

页面由123,变为246,模拟中断,出现了223的情况。看到了更新不完全的DOM。

说明Reconciler和Renderer是交替执行的。

dist

# 16版本

Secheduler - 调度器 调度任务优先级,高优任务优先进入Reconciler

我们以浏览器是否有剩余时间作为任务中断的标准,那么我们需要一种机制,当浏览器有剩余时间时通知我们。

requestIdleCallback (opens new window) 因为这个有兼容性,所以react重写了他,实现了功能更完备的requestIdleCallback的polyfill,这就是 Scheduler (opens new window) 是独立于react的库。

新的-Reconciler - 协调器 负责找到变化的组件

更新工作从递归变成了可以中断的循环过程。每次循环都会调用shouldYield判断当前是否有剩余时间。

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

在React16中,Reconciler与Renderer不再是交替工作。 当Scheduler将任务交给Reconciler后, Reconciler会为变化的虚拟DOM打上代表增/删/更新的标记,类似这样:

export const Placement = /*             */ 0b0000000000010;
export const Update = /*                */ 0b0000000000100;
export const PlacementAndUpdate = /*    */ 0b0000000000110;
export const Deletion = /*              */ 0b0000000001000;

整个Scheduler与Reconciler的工作都在内存中进行。 只有当所有组件都完成Reconciler的工作,才会统一交给Renderer。

Render - 渲染器 - 负责将变化的组件渲染到页面上来 Renderer根据Reconciler为虚拟DOM打的标记,同步执行对应的DOM操作。

process

Last Updated: 9/12/2021, 8:50:43 PM