最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 【微笔记】React Fiber 不完全详解

    正文概述 掘金(碎_浪)   2021-02-25   535

    新的git知识仓库 前端从入门到入土 ~求关注、star及整理需求,不定时更新~


    什么是 Fiber ?

    React Fiber是对核心算法的一次重新实现, 是异步渲染 ui 的解决方案

    出现的背景

    在react15中,更新过程是同步的。当我们调用setState更新页面的时候,React 会遍历应用的所有节点,计算出差异,然后再更新 UI。整个过程是一气呵成,不能被打断的。

    如果页面元素很多,组件树很大的时候,因为更新过程是同步地一层组件套一层组件,逐渐深入的过程,在更新完所有组件之前不停止,函数的调用栈调用得很深,而且很长时间不会返回。整个过程占用的时间可能超过 16 毫秒,就容易出现掉帧的现象。

    举个例子,如果有200个组件要更新,每个组件花费1毫秒,更新完成总共需要200毫秒,在这200毫秒的更新过程中,浏览器唯一的主线程都在专心处理更新操作,无暇去做任何其他的事情。

    如果在这200毫秒内,用户往一个input元素中输入内容,那么敲击键盘不会获得任何响应,因为渲染输入按键结果也是浏览器主线程的工作,但是浏览器主线程被React占用,抽不出空。等React更新过程结束之后,那些字符才会一下子出现在input元素里。

    因为JavaScript单线程的特点,JS 运算、页面布局和页面绘制都是运行在浏览器的主线程当中,他们之间是互斥的关系。如果每个同步任务耗时太长, JS 运算持续占用主线程,程序不会对其他动作作出响应,页面也没法得到及时的更新。

    React的更新过程犯了这个禁忌,而React Fiber就是要改变现状。

    Fiber 的解题思路

    解决主线程长时间被 JS 运算占用这一问题的基本思路,是将运算切割为多个步骤,分批完成。也就是说在完成一部分任务之后,将控制权交回给浏览器,让浏览器有时间进行页面的渲染。等浏览器忙完之后,再继续之前未完成的任务。

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

    旧版 React 通过递归的方式进行渲染,使用的是 JS 引擎自身的函数调用栈,它会一直执行到栈空为止。而Fiber实现了自己的组件调用栈,它以链表的形式遍历组件树,可以灵活的暂停、继续和丢弃执行的任务。

    实现方式是使用了浏览器的requestIdleCallback这一 API。

    React 框架内部的运作可以分为 3 层:

    • Virtual DOM 层,描述页面长什么样。
    • Reconciler 层,负责调用组件生命周期方法,进行 Diff 运算等。
    • Renderer 层,根据不同的平台,渲染出相应的页面,比较常见的是 ReactDOM 和 ReactNative。

    改动最大的当属 Reconciler 层。改动后的 Reconciler 层 称为 Fiber Reconciler,它每执行一段时间,会将控制权交还给浏览器。相对应的,将以前的 Reconciler 被命名为Stack ReconcilerStack Reconciler 运作的过程是不能被打断的,必须一条道走到黑。

    React Fiber把更新过程碎片化,每执行完一段更新过程,就把控制权交还给React负责任务协调的模块,看看有没有其他紧急任务要做,如果没有就继续去更新,如果有紧急任务,那就去做紧急任务。

    为了达到这种效果,就需要有一个调度器 (Scheduler) 来进行任务分配。任务的优先级有六种:

    • synchronous,与之前的Stack Reconciler操作一样,同步执行
    • task,在next tick之前执行
    • animation,下一帧之前执行
    • high,在不久的将来立即执行
    • low,稍微延迟执行也没关系
    • offscreen,下一次render时或scroll时才执行

    优先级高的任务(如键盘输入)可以打断优先级低的任务(如Diff)的执行,从而更快的生效。

    Fiber Reconciler 在执行过程中,会分为 2 个阶段。

    • 阶段一,生成 Fiber 树,得出需要更新的节点信息。这一步是一个渐进的过程,可以被打断。
      该阶段包括

      • componentWillMount
      • componentWillReceiveProps
      • shouldComponentUpdate
      • componentWillUpdate
    • 阶段二,将需要更新的节点一次性批量更新,这个过程不能被打断。
      该阶段包括

      • componentDidMount
      • componentDidUpdate
      • componentWillUnmount

    Fiber树

    Fiber 其实指的是一种数据结构,而Fiber树本质来说是一个链表。

    阶段一有两颗树,Virtual DOM 树和 Fiber 树,Fiber 树是在 Virtual DOM 树的基础上通过额外信息生成的。

    Fiber 树在首次渲染的时候会一次生成。在后续需要 Diff 的时候,会根据已有树和最新 Virtual DOM 的信息,生成一棵新的树。这颗新树每生成一个新的节点,都会将控制权交回给主线程,去检查有没有优先级更高的任务需要执行。如果没有,则继续构建树的过程。

    如果过程中有优先级更高的任务需要进行,则 Fiber Reconciler 会丢弃正在生成的树,在空闲的时候再重新执行一遍。

    题外话

    这里会引出一个知识点,就是在react更新过程中,shouldComponentUpdatecomponentWillUpdate等函数会执行几次。当然,答案是:多次。

    因此,如果有在阶段一的函数中执行的逻辑,必须保证结果的一致性。另外,如果在这几个函数中有网络请求等逻辑的话,务必对可能的重复调用做处理。

    求赞?~
    求关注~
    

    相关阅读

    • react-app-rewired:不使用eject修改create-creact-app配置文件
    • react hook防抖及节流

    参考文档

    1. React Fiber是什么
    2. React.Fiber
    3. [React Fiber 原理介绍](

    起源地下载网 » 【微笔记】React Fiber 不完全详解

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元