Skip to content

第 27 题:说一下 react-fiber #33

@lgwebdream

Description

@lgwebdream
Owner

欢迎在下方发表您的优质见解

Activity

Genzhen

Genzhen commented on Jun 23, 2020

@Genzhen
Collaborator

1)背景

  • react在进行组件渲染时,从setState开始到渲染完成整个过程是同步的(“一气呵成”)。如果需要渲染的组件比较庞大,js执行会占据主线程时间较长,会导致页面响应度变差,使得react在动画、手势等应用中效果比较差。
  • 页面卡顿:Stack reconciler的工作流程很像函数的调用过程。父组件里调子组件,可以类比为函数的递归;对于特别庞大的vDOM树来说,reconciliation过程会很长(x00ms),超过16ms,在这期间,主线程是被js占用的,因此任何交互、布局、渲染都会停止,给用户的感觉就是页面被卡住了。

2)实现原理

旧版 React 通过递归的方式进行渲染,使用的是 JS 引擎自身的函数调用栈,它会一直执行到栈空为止。而Fiber实现了自己的组件调用栈,它以链表的形式遍历组件树,可以灵活的暂停、继续和丢弃执行的任务。实现方式是使用了浏览器的requestIdleCallback这一 API。
Fiber 其实指的是一种数据结构,它可以用一个纯 JS 对象来表示:

const fiber = {
    stateNode,    // 节点实例
    child,        // 子节点
    sibling,      // 兄弟节点
    return,       // 父节点
}
  • react内部运转分三层:
    • Virtual DOM 层,描述页面长什么样。
    • Reconciler 层,负责调用组件生命周期方法,进行 Diff 运算等。
    • Renderer 层,根据不同的平台,渲染出相应的页面,比较常见的是 ReactDOM 和 ReactNative。
  • 为了实现不卡顿,就需要有一个调度器 (Scheduler) 来进行任务分配。优先级高的任务(如键盘输入)可以打断优先级低的任务(如Diff)的执行,从而更快的生效。任务的优先级有六种:
    • synchronous,与之前的Stack Reconciler操作一样,同步执行
    • task,在next tick之前执行
    • animation,下一帧之前执行
    • high,在不久的将来立即执行
    • low,稍微延迟执行也没关系
    • offscreen,下一次render时或scroll时才执行
  • Fiber Reconciler(react )执行阶段:
    • 阶段一,生成 Fiber 树,得出需要更新的节点信息。这一步是一个渐进的过程,可以被打断。
    • 阶段二,将需要更新的节点一次过批量更新,这个过程不能被打断。
  • Fiber树:React 在 render 第一次渲染时,会通过 React.createElement 创建一颗 Element 树,可以称之为 Virtual DOM Tree,由于要记录上下文信息,加入了 Fiber,每一个 Element 会对应一个 Fiber Node,将 Fiber Node 链接起来的结构成为 Fiber Tree。Fiber Tree 一个重要的特点是链表结构,将递归遍历编程循环遍历,然后配合 requestIdleCallback API, 实现任务拆分、中断与恢复。
  • 从Stack Reconciler到Fiber Reconciler,源码层面其实就是干了一件递归改循环的事情
sweetliquid

sweetliquid commented on Nov 4, 2020

@sweetliquid

Component -> Element -> Fiber -> DOM 中间哪来的 VDOM,不存在根据 VDOM 生成 Fiber 一说。

Genzhen

Genzhen commented on Nov 5, 2020

@Genzhen
Collaborator

Component -> Element -> Fiber -> DOM 中间哪来的 VDOM,不存在根据 VDOM 生成 Fiber 一说。
@sweetliquid 感谢提出提出建议

Fiber tree 是React 在 render 第一次渲染时,会通过 React.createElement 创建一颗 Element 树,可以称之为 Virtual DOM Tree,由于要记录上下文信息,加入了 Fiber,每一个 Element 会对应一个 Fiber Node,将 Fiber Node 链接起来的结构成为 Fiber Tree。Fiber Tree 一个重要的特点是链表结构,将递归遍历编程循环遍历,然后配合 requestIdleCallback API, 实现任务拆分、中断与恢复。

qzruncode

qzruncode commented on Apr 14, 2021

@qzruncode

fiber就是一种数据结构,fiber将递归操使用内存来模拟,从而在react pre-commit阶段可以随时打断和恢复,在commit阶段一次性执行完成,所有的effect和hooks,以及任务优先级都是挂在fiber节点上这个优先级其实就是一个expireTime,在expireTime之内的effect都会合并成一个patch一次性更新。剩下的就是diff算法,diff算法和vue的diff类似,采用右移策略看似比vue的低效,但是实际项目中有多少比例的移动操作呢?vue的diff是不管三七二十一都求最长有序序列这个不要时间的吗?

fernandoxu

fernandoxu commented on Aug 19, 2021

@fernandoxu

Component -> Element -> Fiber -> DOM 中间哪来的 VDOM,不存在根据 VDOM 生成 Fiber 一说。
@sweetliquid 感谢提出提出建议

Fiber tree 是React 在 render 第一次渲染时,会通过 React.createElement 创建一颗 Element 树,可以称之为 Virtual DOM Tree,由于要记录上下文信息,加入了 Fiber,每一个 Element 会对应一个 Fiber Node,将 Fiber Node 链接起来的结构成为 Fiber Tree。Fiber Tree 一个重要的特点是链表结构,将递归遍历编程循环遍历,然后配合 requestIdleCallback API, 实现任务拆分、中断与恢复。

React里管Virtual DOM叫React Element吧

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @lgwebdream@Genzhen@sweetliquid@fernandoxu@qzruncode

        Issue actions

          第 27 题:说一下 react-fiber · Issue #33 · lgwebdream/FE-Interview