您现在的位置是:首页 >技术教程 >React Fiber架构网站首页技术教程

React Fiber架构

大莲芒 2024-07-09 10:33:21
简介React Fiber架构

说到Fiber,不得不说说他的发展史:

React15 架构

  • React16之前的版本比对更新虚拟DOM的过程是采用循环递归方式来实现的,这种比对方式有一个问题,就是一旦任务开始进行就无法中断如果应用中数组数量庞大,主线程被长期占用,直到整颗虚拟DOM树比对更新完成之后主线程才被释放,主线程才能执行其他任务,这就会导致一些用户交互或动画等任务无法立即得到执行,页面就会产生卡顿,非常的影响用户体验。

  • 主要原因就是递归无法中断执行重的任务耗时较长,javascript又是单线程的无法同时执行其他任务,导致任务延迟页面卡顿用户体验差

    React15架构可以分为两层

    Reconciler(协调器)—— 负责找出变化的组件 Renderer(渲染器)—— 负责将变化的组件渲染到页面

    每当有更新发生时,Reconciler会做如下工作:

    • 调用函数组件、或class组件的render方法,将返回的JSX转化为虚拟DOM
    • 虚拟DOM和上次更新时的虚拟DOM对比
    • 通过对比找出本次更新中变化的虚拟DOM
    • 通知Renderer将变化的虚拟DOM渲染到页面上

    React15使用的是栈调和器,由于递归执行,所以更新一旦开始,中途就无法中断,当调用层级很深时,递归更新时间超过了屏幕刷新时间间隔,用户交互就会卡顿。

react 16架构

React16架构可以分为三层:

  • Scheduler(调度器)—— 调度任务的优先级,高优任务优先进入Reconciler

  • Reconciler(协调器)—— 负责找出变化的组件

  • Renderer(渲染器)—— 负责将变化的组件渲染到页面上

    相比React15,16增加了一个Scheduler(调度器)

    并发&调度(Concurrency & Scheduler)

  • Concurrency 并发: 有能力优先处理更高优事务,同时对正在执行的中途任务可暂存,待高优完成后,再去执行

  • Scheduler 协调调度: 在浏览器每一帧的时间中,预留一些时间给JS线程,React利用这部分时间更新组件,当预留的时间不够用时,React将线程控制权交还给浏览器使其有时间渲染UI,React则等待下一帧时间到来,继续被中断的工作
    在这里插入图片描述

    在源码中,预留的初始时间是5ms

    考虑到可中断渲染,并可重回构造。React自行实现了一套体系叫做 React fiber 架构。

    Scheduler 运行核心点

    • 有个任务队列 queue,该队列存放可中断的任务。

    • workLoop对队列里取第一个任务currentTask,进入循环开始执行。

    • 当该任务没有时间 或 需要中断 (渲染任务 或 其他高优任务插入等),则让出主线程。

    • requestAnimationFrame 计算一帧的空余时间;

    • 使用new MessageChannel ()执行宏任务;

      Fiber架构

      • 界面通过 vdom 描述,但是不是直接手写 vdom,而是 jsx 编译产生的 render function 之后以后生成的。这样就可以加上 state、props 和一些动态逻辑,动态产生 vdom

      • vdom 生成之后不再是直接渲染,而是先转成 fiber,这个 vdom 转 fiber 的过程叫做 reconcile

      • fiber一个链表结构可以打断,这样就可以通过 requestIdleCallback 来空闲调度 reconcile,这样不断的循环,直到处理完所有的 vdom 转 fiber 的 reconcile,就开始 commit,也就是更新到 dom

      • reconcile 的过程会提前创建好 dom,还会标记出增删改,那么 commit 阶段就很快了。

      • 从之前递归渲染时做 diff 来确定增删改以及创建 dom,提前到了可打断的 reconcile 阶段,让 commit 变得非常快,这就是 fiber 架构的目的和意义。

      Fiber的数据结构有三层信息: (采用链表结构)

    • 实例属性
      Fiber的基本信息,例如组件类型等。

    • 构建属性
      构建属性 (return、child、sibling)

    • 工作属性

      • 数据的变更会导致UI层的变更

      • 为了减少对DOM的直接操作,通过Reconcile进行diff查找,并将需要变更节点,打上标签,变更路径保留在effectList里

      • 待变更内容要有Scheduler优先级处理涉及到diff等查找操作,是需要有个高效手段来处理前后变化,即双缓存机制

      • 链表结构即可支持随时随时中断的诉求

      schedule 就是通过空闲调度每个 fiber节点的reconcile(vdom转fiber),全部reconcile完了就执行commit

      React Fiber 核心: 自行实现 虚拟栈帧

      总结

      • React16 使用的是全新的"Fiber调和器",这就依托于React16的重点了—Fiber架构。
      • React16能够实现中断调和分批次异步地调和。从而达到不因为JS执行时间过久影响浏览器渲染
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。