首页IT科技react fiber执行原理示例解析

react fiber执行原理示例解析

时间2025-06-14 23:34:19分类IT科技浏览5019
导读:为什么要使用fiber,要解决什么问题? 在 react16 引入 Fiber 架构之前,react 会采用递归方法对比两颗虚拟DOM树,找出需要改动的节点,然后同步更新它们,这个过程 react 称为reconcilation(协调)。在reconcilation期间,react 会同步执行操作,提交到真实 D...

为什么要使用fiber             ,要解决什么问题?

在 react16 引入 Fiber 架构之前                  ,react 会采用递归方法对比两颗虚拟DOM树      ,找出需要改动的节点             ,然后同步更新它们                  ,这个过程 react 称为reconcilation(协调)             。在reconcilation期间      ,react 会同步执行操作       ,提交到真实 DOM 的更改                  ,会一直占着浏览器的资源            ,不能中断       ,中断后就不能恢复                   ,使得我们一些用户操作定时器等等事件无法得到响应            ,是一个非常糟糕的用户体验                  。

所以我们要解决的问题就是:解决React主线程长时间占用的一个问题      。 这个时候,就引入了Fiber架构             。

fiber是什么?

Fiber 可以理解为是一个执行单元                   ,也可以理解为是一种数据结构                  。每一个React元素都对应一个fiber对象                  ,我们先看看fiber中的属性:

function FiberNode( tag: WorkTag, pendingProps: mixed, key: null | string, mode: TypeOfMode, ) { // 作为静态数据结构的属性 this.tag = tag; // Fiber对应组件的类型 Function/Class/Host... this.key = key; // key属性 this.elementType = null; // 大部分情况同type,某些情况不同             ,比如FunctionComponent使用React.memo包裹 this.type = null; // 对于 FunctionComponent                  ,指函数本身      ,对于ClassComponent             ,指class                  ,对于HostComponent      ,指DOM节点tagName this.stateNode = null; // Fiber对应的真实DOM节点 // 用于连接其他Fiber节点形成Fiber树 this.parent = null; // 指向父级Fiber节点 this.child = null; // 指向子Fiber节点 this.sibling = null; // 指向右边第一个兄弟Fiber节点 this.index = 0; this.ref = null; // 作为动态的工作单元的属性 —— 保存本次更新造成的状态改变相关信息 this.pendingProps = pendingProps; this.memoizedProps = null; this.updateQueue = null; // class 组件 Fiber 节点上的多个 Update 会组成链表并被包含在 fiber.updateQueue 中      。 函数组件则是存储 useEffect 的 effect 的环状链表       。 this.memoizedState = null; // hook 组成单向链表挂载的位置 this.dependencies = null; this.mode = mode; // Effects this.flags = NoFlags; this.subtreeFlags = NoFlags; this.deletions = null; // 调度优先级相关 this.lanes = NoLanes; this.childLanes = NoLanes; // 指向该fiber在另一次更新时对应的fiber this.alternate = null; }

数据结构

React Fiber 就是采用链表实现的,主要就是通过以下这几个属性表示:

this.parent = null; // 指向父级Fiber节点 this.child = null; // 指向子Fiber节点 this.sibling = null; // 指向右边第一个兄弟Fiber节点

假如我们要渲染下面这个元素树:

<div> <h1> <p> <a></a> </p> </h1> <h2></h2> </div>

我们看一下它的Fiber结构树:

每个fiber元素都有这三个属性       ,观察上面图发现:

parent:指向父级Fiber节点: child:指向子Fiber节点 sibling:指向右边的兄弟节点

执行单元

我们可以把每个fiber当做一个执行单元                  ,每次执行完一个执行单元                  。React会去检测还剩多少时间            ,如果没有时间就将控制权让给浏览器       ,如果还有时间就去执行下一个执行单元            。

这里就涉及到了一个问题                   ,react如何和浏览器进行控制权的交接            ,浏览器何时空闲呢?       。我们先来了解一下浏览器的工作:

浏览器工作:

在浏览器中,我们所看到的页面是一帧一帧画出来的                   ,渲染的帧率与设备的刷新率保持一致                   。通常情况下                  ,我们的设备都是60Hz,也就是说,1s屏幕会刷新60次            。当每秒内绘制的帧数(FPS)超过60时             ,页面渲染是流畅的                  ,当帧数小于60时      ,会明显感受到卡顿。下面来看完整的一帧中             ,浏览器具体做了哪些事情:

首先需要处理输入事件                  ,能够让用户得到最早的反馈 接下来是处理定时器      ,需要检查定时器是否到时间       ,并执行对应的回调 接下来处理 Begin Frame(开始帧)                  ,即每一帧的事件            ,包括 window.resize             、scroll                  、media query change 等 接下来执行请求动画帧 requestAnimationFrame(rAF)       ,即在每次绘制之前                   ,会执行 rAF 回调 紧接着进行 Layout 操作            ,包括计算布局和更新布局,即这个元素的样式是怎样的                   ,它应该在页面如何展示 接着进行 Paint 操作                  ,得到树中每个节点的尺寸与位置等信息,浏览器针对每个元素进行内容填充 到这时以上的六个阶段都已经完成了             ,接下来处于空闲阶段(Idle Peroid)                  ,可以在这时执行 requestIdleCallback 里注册的任务

这样我们把工作单元的任务放到requestIdleCallback回调当中      ,如果浏览器处理完上述的任务(布局和绘制之后)             ,还有盈余时间                  ,这个时候就可以执行我们的工作单元了                   。每次执行完一个执行单元                  。React会去检测还剩多少时间      ,如果没有时间就将控制权让给浏览器。直至       ,React和浏览器通过合作式调度完美配合                  ,实现高性能应用             。

Fiber执行原理

从根节点开始调度和渲染可以分为两个阶段:render和commit                  。 先来了解下这几个关键名词:

workInProgress tree:

workInProgress 代表当前正在执行更新的 Fiber 树      。在 setState或者渲染 后            ,会构建一颗 Fiber 树       ,也就是 workInProgress tree                   ,

currentFiber tree:

首次渲染之后            ,React 会生成一个对应于 UI 渲染的 fiber 树,称之为 current 树             。在新一轮更新时 workInProgress tree 再重新构建                   ,新workInProgress的节点通过 alternate 属性和 currentFiber 的节点建立联系                  。

Effects list:

effect list 可以理解为是一个存储 effect 副作用列表容器      。

render阶段:

在render阶段中                  ,会找到所有节点的变更,比如说节点新增             ,编辑                  ,删除等等       。这些变更React称之为副作用effect                  。在这个阶段中      ,也可以认为是diff阶段,主要就是对比currentFiber tree和workInProgress tree之间的差异             ,然后打上标记            。

在这个阶段                  ,任务是可以终止的       。React 可以根据当前可用的时间片处理一个或多个 fiber 节点      ,并且得益于 fiber 对象中存储的元素上下文信息以及构成的链表结构       ,使其能够将执行到一半的工作仍保存在内存的链表中                   。在重新获得控制权后                  ,又可以根据保存在内存中的上下文信息快速找到停止的fiber节点            ,然后继续工作执行工作单元            。

遍历节点过程:

遍历Fiber tree时采用的是后序遍历方法

从顶部开始遍历 如果有child节点       ,且还未遍历                   ,遍历child节点 如果有child节点            ,且已经遍历过,则遍历sibling节点。 如果没有child节点                   ,返回父节点 如果最后返回的节点为顶部                  ,表示所有节点遍历完成                   。 收集effect list:

在遍历的过程中,我们会去收集所有变更的节点产出的effect,每个effect通过链表的方式链接                  。每个 fiber 有两个属性

firstEffect:指向第一个有副作用的子fiber lastEffect:指向最后一个有副作用的子fiber

中间的使用nextEffect做成一个单链表。

commit阶段:

与render阶段不同,commit阶段是同步操作的             。

为什么commit必须是同步的操作的?

因为在commit阶段是更新真实的dom             ,所以更新dom不可能一点一点去更新                  ,这样用户体验会极差                  。所以commit阶段必须是同步执行      ,一次更新到位      。

首先的事情是遍历effect-list列表,拿到每一个 effect 存储的信息             ,根据副作用类型 effectTag 执行相应的处理并提交更新到真正的 DOM             。所有的effects都会在layout phase阶段之前被处理                  。当该阶段执行结束时                  ,workInProgress树会被替换成current树      。到这里      ,根据收集到的变更信息完成了刷新操作       。

以上就是react fiber执行原理示例解析的详细内容       ,更多关于react fiber执行原理的资料请关注本站其它相关文章!

声明:本站所有文章                  ,如无特殊说明或标注            ,均为本站原创发布                  。任何个人或组织       ,在未征得本站同意时                   ,禁止复制      、盗用             、采集                  、发布本站内容到任何网站      、书籍等各类媒体平台            。如若本站内容侵犯了原著者的合法权益            ,可联系我们进行处理       。

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
快乐赚靠什么赚钱(快乐赚如何看广告-阿姨遇到这四种情况 ,就不要犹豫了,赶紧找个理由下户。…) 黑河SEO关键字优化(黑河seo攻略知识提升)