简介

React 简易实现-Concurrent Mode学习笔记。

上一节存在问题

由上节 render 函数可知,内部递归调用存在以下问题:

1、开始渲染后,直到渲染完完整的元素树后,我们才会停止。如果元素树很大,则可能会阻塞主线程太长时间。

2、而且,如果浏览器需要执行高优先级的操作(例如处理用户输入或保持动画流畅),则它必须等到渲染完成为止。

解决思路

我们将工作分成几个小部分,在完成每个单元后,如果需要执行其他任何操作,我们将让浏览器中断渲染。

使用 requestIdleCallback 进行循环。可以将 requestIdleCallback 视为 setTimeout,但是浏览器将在主线程空闲时运行回调,而不是告诉它何时运行。

requestIdleCallback 还为我们提供了截止日期参数。我们可以使用它来检查浏览器需要再次控制之前需要多少时间。

requestIdleCallback 代码逻辑

let nextUnitOfWork = null;
function workLoop(deadline) {
  let shouldYield = false;
  while (nextUnitOfWork && !shouldYield) {
    nextUnitOfWork = performUnitOfWork(
      nextUnitOfWork
    );
    shouldYield = deadline.timeRemaining() < 1;
  }
  // == 在未来的帧中继续执行
  requestIdleCallback(workLoop);
}
requestIdleCallback(workLoop);

// == 不仅执行当前工作单元,同时返回下一个工作单元
function performUnitOfWork(nextUnitOfWork) {
  // TODO
}

requestIdleCallback 存在缺陷

requestIdleCallback 使用可参考 https://zhuanlan.zhihu.com/p/60189423

requestIdleCallback 的 FPS 只有 20, 这远远低于页面流畅度的要求!(一般 FPS 为 60 时对用户来说是感觉流程的, 即一帧时间为 16.7ms)。

这也是 React 需要自己实现 requestIdleCallback 的原因。

React 不再使用 requestIdleCallback 。React 使用 scheduler 包

项目地址

地址: https://github.com/yunaichun/react-study/tree/master/react-simple/simple-two

参考资料

powered by Gitbook该文件修订时间: 2023-05-16 18:08:03

results matching ""

    No results matching ""