前言

React Fiber  机制是16版本性能重大提升的关键,也是react 面试的核心问题;

一、React 的工作流程

React渲染页面的两个阶段

  • 调和阶段(reconciliation):在这个阶段 React 会更新数据生成新的 Virtual DOM,然后通过Diff算法,快速找出需要更新的元素,放到更新队列中去,得到新的更新队列,以及记录commit 阶段将要执行的生命周期函数
  • 渲染阶段(commit):这个阶段 React 会遍历更新队列,将其所有的变更一次性更新到DOM上,并执行上一步调和阶段记录的生命周期函数

    React15架构可以分为两层:

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

  在React15及以前,Reconciler采用递归的方式创建虚拟DOM,递归过程是不能中断的。如果组件树的层级很深,递归会占用线程很多时间,递归更新时间超过了16ms,用户交互就会卡顿。

React16架构可以分为三层:

从v15到v16,React团队花了两年时间将源码架构中的Stack Reconciler重构为Fiber Reconciler 也即React 的Fiber 机制

  • Scheduler(调度器)—— 调度任务的优先级,高优任务优先进入Reconciler;
  • Reconciler(协调器)—— 负责找出变化的组件:更新工作从递归变成了可以中断的循环过程。Reconciler内部采用了Fiber的架构
  • Renderer(渲染器)—— 负责将变化的组件渲染到页面上。

二、什么是Fiber

 在 React 中,Fiber 就是 React 16 实现的一套新的更新机制,让 React 的更新过程变得可控,避免了之前采用递归需要一气呵成影响性能的做法。

1.React Fiber 中的时间分片

 把一个耗时长的任务分成很多小片,每一个小片的运行时间很短,虽然总时间依然很长,但是在每个小片执行完之后,都给其他任务一个执行的机会,这样唯一的线程就不会被独占,其他任务依然有运行的机会。

  React Fiber 把更新过程碎片化,每执行完一段更新过程,就把控制权交还给 React 负责任务协调的模块,看看有没有其他紧急任务要做,如果没有就继续去更新,如果有紧急任务,那就去做紧急任务;
 现在 部分浏览器 已经实现了对应的API  ——requestIdleCallback

资料参考:requestIdleCallback --后台任务调度

2. React   Stack Reconciler
 基于栈的 Reconciler,浏览器引擎会从执行栈的顶端开始执行,执行完毕就弹出当前执行上下文,开始执行下一个函数,直到执行栈被清空才会停止。然后将执行权交还给浏览器。由于 React 将页面视图视作一个个函数执行的结果。每一个页面往往由多个视图组成,这就意味着多个函数的调用。

  如果一个页面足够复杂,形成的函数调用栈就会很深。每一次更新,执行栈需要一次性执行完成,中途不能干其他的事儿,只能"一心一意"。结合前面提到的浏览器刷新率,JS 一直执行,浏览器得不到控制权,就不能及时开始下一帧的绘制。如果这个时间超过 16ms,当页面有动画效果需求时,动画因为浏览器不能及时绘制下一帧,这时动画就会出现卡顿。不仅如此,因为事件响应代码是在每一帧开始的时候执行,如果不能及时绘制下一帧,事件响应也会延迟。

3.   Fiber  Reconciler
在 React Fiber 中用链表遍历的方式替代了 React 16 之前的栈递归方案。在 React 16 中使用了大量的链表。其好处是

链表相比顺序结构数据格式的好处就是:

  • 操作更高效,比如顺序调整、删除,只需要改变节点的指针指向就好了。
  • 不仅可以根据当前节点找到下一个节点,在多向链表中,还可以找到他的父节点或者兄弟节点。
  • React 用空间换时间,更高效的操作可以方便根据优先级进行操作。同时可以根据当前节点找到其他节点

4.  Fiber 
React Fiber 给每个任务分配了优先级。具体点就是在创建或者更新 FiberNode 的时候,通过算法给每个任务分配一个到期时间(expirationTime)。在每个任务执行的时候除了判断剩余时间,如果当前处理节点已经过期,那么无论现在是否有空闲时间都必须执行该任务。过期时间的大小还代表着任务的优先级。

  任务在执行过程中顺便收集了每个 FiberNode 的副作用,将有副作用的节点通过 firstEffect、lastEffect、nextEffect 形成一条副作用单链表 A1(TEXT)-B1(TEXT)-C1(TEXT)-C1-C2(TEXT)-C2-B1-B2(TEXT)-B2-A。

  其实最终都是为了收集到这条副作用链表,有了它,在接下来的渲染阶段就通过遍历副作用链完成 DOM 更新。这里需要注意,更新真实 DOM 的这个动作是一气呵成的,不能中断,不然会造成视觉上的不连贯(commit)。

总结

1.Fiber  从底层给react  工作流实现了重大的重构,目标 达到 从重构的目标是实现Concurrent Mode(并发模式)。 根据 Firber 的时间切片,分配每一段任务优先级,从而实现可中断可控的更新操作。最终使得应用运行流畅,看起来很快。

React Fiber 机制相关推荐

  1. React Fiber架构原理剖析

    一.概述 在 React 16 之前,VirtualDOM 的更新采用的是Stack架构实现的,也就是循环递归方式.不过,这种对比方式有明显的缺陷,就是一旦任务开始进行就无法中断,如果遇到应用中组件数 ...

  2. React Fiber 原理介绍

    欢迎关注我的公众号睿Talk,获取我最新的文章: 一.前言 在 React Fiber 架构面世一年多后,最近 React 又发布了最新版 16.8.0,又一激动人心的特性:React Hooks 正 ...

  3. 转载:React Fiber架构(浅显易懂)

    性能优化是一个系统性的工程,如果只看到局部,引入算法,当然是越快越好; 但从整体来看,在关键点引入缓存,可以秒杀N多算法,或另辟蹊径,探索事件的本质,可能用户要的并不是快-- React16启用了全新 ...

  4. 浅析 React Fiber

    引言 在 react 进入大家视野之初,Virtual DOM(VDOM)的概念让人眼前一亮,在操作真正的 DOM 之前,先通过 VDOM 前后对比得出需要更新的部分,再去操作真实的 DOM,减少了浏 ...

  5. 六个问题让你更懂 React Fiber

    作者 | 零一0101 来源 | 前端印象 React Fiber 是Facebook花费两年余时间对 React 做出的一个重大改变与优化,是对 React 核心算法的一次重新实现.从Faceboo ...

  6. 前端工程师的自我修养:React Fiber 是如何实现更新过程可控的

    前言 从 React 16 开始,React 采用了 Fiber 机制替代了原先基于原生执行栈递归遍历 VDOM 的方案,提高了页面渲染性能和用户体验.乍一听 Fiber 好像挺神秘,在原生执行栈都还 ...

  7. 这可能是最通俗的 React Fiber 打开方式

    作者:荒山 https://juejin.im/post/5dadc6045188255a270a0f85 温馨提示:由于 wx 外链限制,文中外链请点击阅读原文查看. 写一篇关于 React Fib ...

  8. React Fiber 原理

    持续学习中- 源码版本: v17.0.1, 官方源码地址 源码调试教程 调试的源码 画图软件 浏览器的一帧 浏览器中, 页面都是一帧一帧的绘制出来的, 渲染的帧率和设备的刷新率是一致的, 以常用的显示 ...

  9. react fiber架构学习

    同步更新过程的局限 在v16版本以前,react的更新过程是通过递归从根组件树开始同步进行的,更新过程无法被打断,当组件树很大的时候就会出现卡顿的问题 react中的虚拟dom import Reac ...

最新文章

  1. SAP MM 向交货单的存在不阻止PO被删除
  2. DeepMind-深度学习: AI革命及其前沿进展 (54页ppt报告)
  3. IBM携手天健“漫步”区域医疗信息化市场
  4. NEO从源码分析看nep2与nep6
  5. 信号与系统:快速傅里叶变换FFT中的实际频率(奈奎斯特频率解析)
  6. 小龟小车A2学习笔记
  7. 加密(Asp.Net配置文件的)配置节
  8. 2-计算机发展及应用
  9. 学linux需要关闭防火墙,一起学习linux 关闭防火墙命令
  10. 计算机网络之应用层:2、DNS域名解析系统
  11. 2019全球程序员薪酬报告:软件开发比机器学习抢手!40岁后收入下滑
  12. DSSM算法-计算文本相似度
  13. 详解:Sqoop的安装
  14. get buffer from CMSampleBufferRef
  15. Excel(九)-怎样让你的Excel界面更干净?
  16. 订单生产计划表范本_生产计划表(生产计划表格模板)
  17. pyhton中matplotlib箱线图的绘制(matplotlib双轴图、箱线图、散点图以及相关系数矩阵图))...
  18. 考研英语近义词与反义词·十三
  19. 微信公众号采集方案(基于Windows逆向)
  20. ANSYS中vonnbsp;misesnbsp;stres…

热门文章

  1. 徒手写个Java中间件
  2. 谷歌输入法的英文联想功能(v3.0 beta)
  3. 易观方舟Argo社区生态壮大 “春雨计划”蓄势待发
  4. 再好的接口也挡不住程序员敏锐的眼睛
  5. kafka系列(五)—— broker存储结构
  6. SSM --Spring 第一天
  7. linux deepin 进入桌面,让deepin系统用上gnome桌面环境,附成功的经验分享
  8. Sleep()函数的理解、使用、意义
  9. 开发android机顶盒应用 事件,焦点处理
  10. 四季靓汤—瘦肉鸡骨草煲蜜枣汤