We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
React 的核心流程可以分为两个部分:
如需要,则操作 dom 节点更新;
假设前端更新一个组件需要 1ms,如果有200个组件要更新,那就需要 200ms,在这200ms的更新过程中,浏览器唯一的主线程都在专心运行更新操作,无暇去做任何其他的事情。在这 200ms 内,用户往一个 input 元素中输入点什么,回车时不会获得响应,因为渲染输入按键结果需要浏览器主线程的工作,但是浏览器主线程被占用,最后的结果就是用户敲了按键看不到反应,等更新过程结束之后,那些按键会一下出现在 input 元素里,这就是界面卡顿。
我们都知道浏览器是单线程的,当遇到大计算量的操作或者设备性能不足会使页面掉帧,导致卡顿。市面上主流显示屏刷新频率为60Hz,即每(1000ms / 60Hz)16.6ms屏幕刷新一次,业务所包含大量的组件渲染(或数据)会导致主进程长时间被占用,导致一些动画或高频操作出现卡顿和掉帧的情况 。这个过程也是同步阻塞 此时就会由同步阻塞 在之前的调度算法中,React 需要实例化每个类组件,生成一颗组件树,使用 同步递归 的方式进行遍历渲染,而这个过程最大的问题就是无法 暂停和恢复。
解决方案: 解决同步阻塞的方法,通常有两种**: 异步化 和 任务分割**。而 React Fiber 便是为了实现任务分割而诞生的。
React Fiber 解决这个问题的思路是把渲染/更新过程(递归diff)拆分成一系列小任务。每次检查树上的一小部分,做完看是否还有时间继续下一个任务,有的话继续,没有的话把自己挂起,主线程不忙的时候再继续
先写一个 demo,简化一下问题
执行下面的代码,浏览器会有10s左右的时间处于卡死状态:无法滚动、无法编辑、无法关闭tab
function repeat(str, count){ let result = '' for(let i = 0; i < count; i++){ result += str } return result; } console.log(repeat('1', 9999999))
按照任务拆分 的设计思想,拆分计算任务,来解决页面卡死的问题
async function repeat(str, count){ let maxLoopCount = 999999; let loopCount = 0; async function runTask(count) { let newStr = '' return new Promise((resolve, reject) => { window.requestAnimationFrame(() => { for (let i = 0; i < count && i < maxLoopCount; i++) { loopCount++ newStr += str; } resolve(newStr); }); }); } while (loopCount < count) { taskStr += await runTask(count - loopCount); } return taskStr; } repeat('1', 99999999).then(result => console.log(result))
fiber tree 本质上是个单链表(Singly Linked List)树结构,react 以 虚拟 DOM 节点 为单位拆分计算任务,树的遍历完成,代表计算任务的完成
js 线程如果占用主线程太长时间,会影响页面本身的渲染任务
通过拆分 js 任务,保证在不影响渲染进程的前提下,实现js复杂任务的计算
当然React在fiber的处理上远复杂的多,有兴趣的同学可以去深究下
http://www.ayqy.net/blog/dive-into-react-fiber/
https://juejin.cn/post/6844903801153945608
The text was updated successfully, but these errors were encountered:
No branches or pull requests
React 的核心流程可以分为两个部分:
render阶段
commit阶段
如需要,则操作 dom 节点更新;
背景:
假设前端更新一个组件需要 1ms,如果有200个组件要更新,那就需要 200ms,在这200ms的更新过程中,浏览器唯一的主线程都在专心运行更新操作,无暇去做任何其他的事情。在这 200ms 内,用户往一个 input 元素中输入点什么,回车时不会获得响应,因为渲染输入按键结果需要浏览器主线程的工作,但是浏览器主线程被占用,最后的结果就是用户敲了按键看不到反应,等更新过程结束之后,那些按键会一下出现在 input 元素里,这就是界面卡顿。
产生的原因
我们都知道浏览器是单线程的,当遇到大计算量的操作或者设备性能不足会使页面掉帧,导致卡顿。市面上主流显示屏刷新频率为60Hz,即每(1000ms / 60Hz)16.6ms屏幕刷新一次,业务所包含大量的组件渲染(或数据)会导致主进程长时间被占用,导致一些动画或高频操作出现卡顿和掉帧的情况 。这个过程也是同步阻塞
此时就会由同步阻塞 在之前的调度算法中,React 需要实例化每个类组件,生成一颗组件树,使用 同步递归 的方式进行遍历渲染,而这个过程最大的问题就是无法 暂停和恢复。
解决方案: 解决同步阻塞的方法,通常有两种**: 异步化 和 任务分割**。而 React Fiber 便是为了实现任务分割而诞生的。
React Fiber 解决这个问题的思路是把渲染/更新过程(递归diff)拆分成一系列小任务。每次检查树上的一小部分,做完看是否还有时间继续下一个任务,有的话继续,没有的话把自己挂起,主线程不忙的时候再继续
先写一个 demo,简化一下问题
demo
执行下面的代码,浏览器会有10s左右的时间处于卡死状态:无法滚动、无法编辑、无法关闭tab
按照任务拆分 的设计思想,拆分计算任务,来解决页面卡死的问题
Fiber-回到问题本质
fiber tree 本质上是个单链表(Singly Linked List)树结构,react 以 虚拟 DOM 节点 为单位拆分计算任务,树的遍历完成,代表计算任务的完成
js 线程如果占用主线程太长时间,会影响页面本身的渲染任务
通过拆分 js 任务,保证在不影响渲染进程的前提下,实现js复杂任务的计算
当然React在fiber的处理上远复杂的多,有兴趣的同学可以去深究下
参考
http://www.ayqy.net/blog/dive-into-react-fiber/
https://juejin.cn/post/6844903801153945608
The text was updated successfully, but these errors were encountered: