看了一篇官网推荐的Github文章,一篇淘系前端文章,快速看了掘金两篇大佬文章,写下这篇总结
Fiber 是 React 16 中新的
协调引擎
。它的主要目的是使 Virtual DOM 可以进行增量式渲染。了解更多.Fiber reconciler
“fiber” reconciler(调节器,用来diff的) 是一个新尝试,致力于解决 stack reconciler 中固有的问题,同时解决一些历史遗留问题。Fiber 从 React 16 开始变成了默认的 reconciler。
它的主要目标是:
- 能够把可中断的任务切片处理。
- 能够调整优先级,重置并复用任务。
- 能够在父元素与子元素之间交错处理,以支持 React 中的布局。
- 能够在
render()
中返回多个元素。- 更好地支持错误边界。
你可以在这里和这里,深入了解 React Fiber 架构。虽然这已经在 React 16 中启用了,但是 async 特性还没有默认开启。
React的更新关键点:
React是协调器和渲染器分离的,协调器负责计算树的哪些部分发生了变化;然后渲染器使用该信息来实际更新渲染的应用程序。这种分离意味着 React DOM 和 React Native 可以使用自己的渲染器,同时共享由 React 核心提供的相同的协调器。Fiber 重新实现了协调器。它主要不涉及渲染,尽管渲染器需要更改以支持(并利用)新架构。
如果有东西在屏幕外,我们可以延迟与之相关的任何逻辑。如果数据到达速度快于帧速率,我们可以合并和批量更新。我们可以将来自用户交互的工作(例如由按钮点击引起的动画)优先于不太重要的后台工作(例如渲染刚从网络加载的新内容),以避免丢帧。
关键点是:
scheduling:确定何时应该执行工作的过程。所以就是 何时执行更新的结果过程。
work:必须执行的任何计算。工作通常是更新的结果(例如setState
)。
React Fiber 的目标是提高其对动画、布局( animation, layout, and gestures)等领域的适用性。它的主要功能是增量渲染:能够将渲染工作分成块并将其分散到多个帧上。
Fiber 是对 React 核心算法的重构,facebook 团队使用两年多的时间去重构 React 的核心算法,在React16 以上的版本中引入了 Fiber 架构,其中的设计思想是非常值得我们学习的。
我们已经确定 Fiber 的主要目标是使 React 能够利用调度。具体来说,我们需要能够
为了做到这一点,我们首先需要一种将工作分解成单元的方法,从某种意义上说,一个fiber就是一个工作单元
较新的浏览器(和 React Native)实现的 API 有助于解决这个确切的问题:requestIdleCallback
安排一个低优先级的函数在空闲期间调用,并requestAnimationFrame
安排一个高优先级的函数在下一个动画帧上调用。问题是,为了使用这些 API,您需要一种将渲染工作分解为增量单元的方法
。如果你只依赖调用栈,它会一直工作直到栈为空。
如果我们可以自定义调用堆栈的行为来优化渲染 UI,那不是很好吗?如果我们可以随意中断调用堆栈并手动操作堆栈帧,那不是很好吗?
这就是 React Fiber 的目的。Fiber 是堆栈的重新实现,专门用于 React 组件。
重新实现堆栈的优点是您可以将堆栈帧保存在内存中
,并根据需要(以及任何时候)执行它们。这对于实现我们的调度目标至关重要。
具体来说,fiber是一个 JavaScript 对象,其中包含有关组件、其输入和输出的信息。
一个fiber对应一个栈帧,但也对应一个组件的实例。
未来部分:
type和key
type对于复合组件,类型是函数或类组件本身。对于宿主组件(div、span等),类型是字符串。
key决定是否复用
child和sibling
//这些字段指向其他fiber,描述fiber的递归树结构。
//子fiber对应于组件render方法返回的值
function Parent() {
return <Child />
}
//兄弟字段解释了render返回多个子项的情况(Fiber 中的一个新功能!):
function Parent() {
return [<Child1 />, <Child2 />]
}
//子fiber形成一个单向链表,其头部是第一个子fiber。因此,在这个例子中,Child1是Parent的孩子,Child1的兄弟是Child2。
return
//return是程序在处理当前fiber后应返回的fiber。它在概念上与堆栈帧的返回地址相同。它也可以被认为是父fiber。
//如果一个fiber有多个子fiber,则每个子fiber的返回fiber都是父fiber。所以在上一节的例子中,Child1返回fiberChild2是Parent。
pendingProps
和 memoizedProps
//从概念上讲,props 是函数的参数。fiber`pendingProps`在执行开始时`memoizedProps`设置,并在执行结束时设置。
//当传入`pendingProps`等于 时`memoizedProps`,表示可以重复使用fiber先前的输出,从而防止不必要的工作。
pendingWorkPriority
一个数字,表示纤程所代表的工作的优先级。除NoWork
0 外,数字越大表示优先级越低。例如,您可以使用以下函数来检查fiber的优先级是否至少与给定级别一样高:
function matchesPriority(fiber, priority) {
return fiber.pendingWorkPriority !== 0 &&
fiber.pendingWorkPriority <= priority
}
调度程序使用优先级字段来搜索下一个要执行的工作单元。
alternate
(交替,轮流)
//flush
刷新fiber就是将其输出渲染到屏幕上
//work-in-progress
尚未完成的fiber;从概念上讲,尚未返回的堆栈帧。
//在任何时候,一个组件实例最多有两个与之对应的fiber:当前的、已刷新的纤程和正在进行中的纤程。
//A fiber's alternate is created lazily using a function called cloneFiber。与其总是创建一个新对象,不如cloneFiber尝试重用fiber的备用对象(如果存在),从而最大限度地减少分配。
output
//host component 宿主组件
React 应用程序的叶节点。它们特定于渲染环境(例如,在浏览器应用程序中,它们是`div`、`span` 等)。在 JSX 中,它们使用lowercase tag。
从概念上讲,fiber的输出是函数的返回值。
每个fiber最终都有输出,但输出仅在叶节点由host components创建。然后将输出沿树向上传输。
输出是最终提供给渲染器的内容,以便它可以将更改刷新到渲染环境。定义如何创建和更新输出是渲染器的责任。