文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

react中fiber有什么用

2024-04-02 19:55

关注

这篇文章给大家分享的是有关react中fiber有什么用的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。

Fiber是React新的调度算法,是对核心算法的一次重新实现。React Fiber把更新过程碎片化,每执行完一段更新过程,就把控制权交还给React负责任务协调的模块,看看有没有其他紧急任务要做,如果有紧急任务,就去做紧急任务。

react中fiber有什么用

本教程操作环境:Windows7系统、react17.0.1版、Dell G3电脑。

react16 版本之后引入了 fiber,整个架构层面的 调度、协调、diff 算法以及渲染等都与 fiber 密切相关。

React Fiber是个什么东西呢?

react在进行组件渲染时,从setState开始到渲染完成整个过程是同步的(“一气呵成”)。如果需要渲染的组件比较庞大,js执行会占据主线程时间较长,会导致页面响应度变差,使得react在动画、手势等应用中效果比较差。

为了解决这个问题,react团队经过两年的工作,重写了react中核心算法——reconciliation。并在v16版本中发布了这个新的特性。为了区别之前和之后的reconciler,通常将之前的reconciler称为stack reconciler,重写后的称为fiber reconciler,简称为Fiber。

官方的一句话解释是“React Fiber是对核心算法的一次重新实现”。

Fiber 可以提升复杂React 应用的可响应性和性能。Fiber 即是React新的调度算法(reconciliation algorithm)

React Fiber 把更新过程碎片化,每执行完一段更新过程,就把控制权交还给 React 负责任务协调的模块,看看有没有其他紧急任务要做,如果没有就继续去更新,如果有紧急任务,那就去做紧急任务。

react在进行组件渲染时,从setState开始到渲染完成整个过程是同步的(“一气呵成”)。如果需要渲染的组件比较庞大,js执行会占据主线程时间较长,会导致页面响应度变差,使得react在动画、手势等应用中效果比较差。

为了解决这个问题,react团队经过两年的工作,重写了react中核心算法——reconciliation。并在v16版本中发布了这个新的特性。为了区别之前和之后的reconciler,通常将之前的reconciler称为stack reconciler,重写后的称为fiber reconciler,简称为Fiber。

react中fiber有什么用

react中fiber有什么用

卡顿原因

Stack reconciler的工作流程很像函数的调用过程。父组件里调子组件,可以类比为函数的递归(这也是为什么被称为stack reconciler的原因)。在setState后,react会立即开始reconciliation过程,从父节点(Virtual DOM)开始遍历,以找出不同。将所有的Virtual DOM遍历完成后,reconciler才能给出当前需要修改真实DOM的信息,并传递给renderer,进行渲染,然后屏幕上才会显示此次更新内容。对于特别庞大的vDOM树来说,reconciliation过程会很长(x00ms),在这期间,主线程是被js占用的,因此任何交互、布局、渲染都会停止,给用户的感觉就是页面被卡住了。

react中fiber有什么用

Scheduler

scheduling(调度)是fiber reconciliation的一个过程,主要决定应该在何时做什么。?的过程表明在stack reconciler中,reconciliation是“一气呵成”,对于函数来说,这没什么问题,因为我们只想要函数的运行结果,但对于UI来说还需要考虑以下问题:

所以理想状况下reconciliation的过程应该是像下图所示一样,每次只做一个很小的任务,做完后能够“喘口气儿”,回到主线程看下有没有什么更高优先级的任务需要处理,如果又则先处理更高优先级的任务,没有则继续执行(cooperative scheduling 合作式调度)。

react中fiber有什么用

任务拆分 fiber-tree & fiber

先看一下stack-reconciler下的react是怎么工作的。代码中创建(或更新)一些元素,react会根据这些元素创建(或更新)Virtual DOM,然后react根据更新前后virtual DOM的区别,去修改真正的DOM。注意,在stack reconciler下,DOM的更新是同步的,也就是说,在virtual DOM的比对过程中,发现一个instance有更新,会立即执行DOM操作

react中fiber有什么用

而fiber-conciler下,操作是可以分成很多小部分,并且可以被中断的,所以同步操作DOM可能会导致fiber-tree与实际DOM的不同步。对于每个节点来说,其不光存储了对应元素的基本信息,还要保存一些用于任务调度的信息。因此,fiber仅仅是一个对象,表征reconciliation阶段所能拆分的最小工作单元,和上图中的react instance一一对应。通过stateNode属性管理Instance自身的特性。通过child和sibling表征当前工作单元的下一个工作单元,return表示处理完成后返回结果所要合并的目标,通常指向父节点。整个结构是一个链表树。每个工作单元(fiber)执行完成后,都会查看是否还继续拥有主线程时间片,如果有继续下一个,如果没有则先处理其他高优先级事务,等主线程空闲下来继续执行。

react中fiber有什么用

fiber {  	stateNode: {},    child: {},    return: {},    sibling: {},
}复制代码

举个例子

当前页面包含一个列表,通过该列表渲染出一个button和一组Item,Item中包含一个div,其中的内容为数字。通过点击button,可以使列表中的所有数字进行平方。另外有一个按钮,点击可以调节字体大小。

react中fiber有什么用

页面渲染完成后,就会初始化生成一个fiber-tree。初始化fiber-tree和初始化Virtual DOM tree没什么区别,这里就不再赘述。

react中fiber有什么用

于此同时,react还会维护一个workInProgressTree。workInProgressTree用于计算更新,完成reconciliation过程。

react中fiber有什么用

用户点击平方按钮后,利用各个元素平方后的list调用setState,react会把当前的更新送入list组件对应的update queue中。但是react并不会立即执行对比并修改DOM的操作。而是交给scheduler去处理。

react中fiber有什么用

scheduler会根据当前主线程的使用情况去处理这次update。为了实现这种特性,使用了requestIdelCallbackAPI。对于不支持这个API的浏览器,react会加上pollyfill。

总的来讲,通常,客户端线程执行任务时会以帧的形式划分,大部分设备控制在30-60帧是不会影响用户体验;在两个执行帧之间,主线程通常会有一小段空闲时间,requestIdleCallback可以在这个空闲期(Idle Period)调用空闲期回调(Idle Callback),执行一些任务

react中fiber有什么用

一旦reconciliation过程得到时间片,就开始进入work loop。work loop机制可以让react在计算状态和等待状态之间进行切换。为了达到这个目的,对于每个loop而言,需要追踪两个东西:下一个工作单元(下一个待处理的fiber);当前还能占用主线程的时间。第一个loop,下一个待处理单元为根节点。

react中fiber有什么用

因为根节点上的更新队列为空,所以直接从fiber-tree上将根节点复制到workInProgressTree中去。根节点中包含指向子节点(List)的指针。

react中fiber有什么用

根节点没有什么更新操作,根据其child指针,接下来把List节点及其对应的update queue也复制到workinprogress中。List插入后,向其父节点返回,标志根节点的处理完成。

react中fiber有什么用

根节点处理完成后,react此时检查时间片是否用完。如果没有用完,根据其保存的下个工作单元的信息开始处理下一个节点List。

react中fiber有什么用

接下来进入处理List的work loop,List中包含更新,因此此时react会调用setState时传入的updater funciton获取最新的state值,此时应该是[1,4,9]。通常我们现在在调用setState传入的是一个对象,但在使用fiber conciler时,必须传入一个函数,函数的返回值是要更新的state。react从很早的版本就开始支持这种写法了,不过通常没有人用。在之后的react版本中,可能会废弃直接传入对象的写法。

setState({}, callback); // stack concilersetState(() => { return {} }, callback); // fiber conciler复制代码

在获取到最新的state值后,react会更新List的state和props值,然后调用render,然后得到一组通过更新后的list值生成的elements。react会根据生成elements的类型,来决定fiber是否可重用。对于当前情况来说,新生成的elments类型并没有变(依然是Button和Item),所以react会直接从fiber-tree中复制这些elements对应的fiber到workInProgress 中。并给List打上标签,因为这是一个需要更新的节点。

react中fiber有什么用

List节点处理完成,react仍然会检查当前时间片是否够用。如果够用则处理下一个,也就是button。加入这个时候,用户点击了放大字体的按钮。这个放大字体的操作,纯粹由js实现,跟react无关。但是操作并不能立即生效,因为react的时间片还未用完,因此接下来仍然要继续处理button。

react中fiber有什么用

button没有任何子节点,所以此时可以返回,并标志button处理完成。如果button有改变,需要打上tag,但是当前情况没有,只需要标记完成即可。

react中fiber有什么用

老规矩,处理完一个节点先看时间够不够用。注意这里放大字体的操作已经在等候释放主线程了。

react中fiber有什么用

接下来处理第一个item。通过shouldComponentUpdate钩子可以根据传入的props判断其是否需要改变。对于第一个Item而言,更改前后都是1,所以不会改变,shouldComponentUpdate返回false,复制div,处理完成,检查时间,如果还有时间进入第二个Item。

第二个Item shouldComponentUpdate返回true,所以需要打上tag,标志需要更新,复制div,调用render,讲div中的内容从2更新为4,因为div有更新,所以标记div。当前节点处理完成。

react中fiber有什么用

对于上面这种情况,div已经是叶子节点,且没有任何兄弟节点,且其值已经更新,这时候,需要将此节点改变产生的effect合并到父节点中。此时react会维护一个列表,其中记录所有产生effect的元素。

react中fiber有什么用

合并后,回到父节点Item,父节点标记完成。

react中fiber有什么用

下一个工作单元是Item,在进入Item之前,检查时间。但这个时候时间用完了。此时react必须交换主线程,并告诉主线程以后要为其分配时间以完成剩下的操作。

react中fiber有什么用

主线程接下来进行放大字体的操作。完成后执行react接下来的操作,跟上一个Item的处理流程几乎一样,处理完成后整个fiber-tree和workInProgress如下:

react中fiber有什么用

完成后,Item向List返回并merge effect,effect List现在如下所示:

react中fiber有什么用

此时List向根节点返回并merge effect,所有节点都可以标记完成了。此时react将workInProgress标记为pendingCommit。意思是可以进入commit阶段了。

react中fiber有什么用

此时,要做的是还是检查时间够不够用,如果没有时间,会等到时间再去提交修改到DOM。进入到阶段2后,reacDOM会根据阶段1计算出来的effect-list来更新DOM。

更新完DOM之后,workInProgress就完全和DOM保持一致了,为了让当前的fiber-tree和DOM保持一直,react交换了current和workinProgress两个指针。

react中fiber有什么用

事实上,react大部分时间都在维持两个树(Double-buffering)。这可以缩减下次更新时,分配内存、垃圾清理的时间。commit完成后,执行componentDidMount函数。

小结

通过将reconciliation过程,分解成小的工作单元的方式,可以让页面对于浏览器事件的响应更加及时。但是另外一个问题还是没有解决,就是如果当前在处理的react渲染耗时较长,仍然会阻塞后面的react渲染。这就是为什么fiber reconciler增加了优先级策略。

感谢各位的阅读!关于“react中fiber有什么用”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-前端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯