React-fiber架构的解释
React-fiber架构解析
什么是fiber
React中虚拟dom是对真实dom的一种简化,但是一些真实dom能做的事情,虚拟dom做不了,于是就有了fiber,fiber其实是指一种数据结构,有很多的属性,它可以用一个纯的JS对象来表示,借由fiber上的属性做到一些虚拟dom功能上的拓展
//简化的fiber对象
const fiber={tag,//fiber类型key,type,//标签类型stateNode, //当前fiber实例child, //子节点subling, //兄弟节点return, //父节点index,memoizedState,//当前fiber的statememoizedProps//当前fiber的propspendingProps,//传进来的新的propseffectTag,//当前节点要进行何等更新 placement新插入 update更新 deletion删除 placementAndUpdate插入加更新 noWork当前节点没有任何工作firstEffect,//当前有更新的第一个子节点lastEffect,//当前节点有更新的最后一个子节点nextEffect,//下一个要跟更新的子节点alternate,//连接current和workInProgress树updateQueue,//一条链表挂载的是当前fiber的新的状态//....其他属性
}
一、fiber架构
以往版本不足:
界面DOM节点多,渲染比较耗时
React为了弥补之前版本的一些不足,设计了一些新的算法,由新算法设计出现了fiber这种数据结构
fiber数据结构+新的算法=fiber架构
JSX:React语法糖 描述UI界面
1.1、react应用从始至中管理这基本的三样东西
1、Root-- (应用根 一个对象 存在一个属性指向current树,一个属性指向workInProgress树 )
2、current树 (保存上一次状态的fiber树 ,且每个fiber节点都对应这一个jsx节点)
3、workInProgress树(保存每次新的状态的fiber树,并且每个fiber节点都对应一个jsx节点)
1.2、react初次渲染
1、react在第一次开始创建root时, 就会同时创建uninitialFiber对象 (未初始化的fiber)、
使react的current指向了uninitialFiber对象 假设为上一次状态
2、之后再去创建本次要用到的workInProgress树
二、Fiber 的主要工作流程:
ReactDOM.render()
引导 React 启动或调用setState()
的时候开始创建或更新 Fiber 树。- 从根节点开始遍历 Fiber Node Tree, 并且构建 WokeInProgress Tree(reconciliation 阶段)。
- 本阶段可以暂停、终止、和重启,会导致 react 相关生命周期重复执行。
- React 会生成两棵树,一棵是代表当前状态的 current tree,一棵是待更新的 workInProgress tree。
- 遍历 current tree,重用或更新 Fiber Node 到 workInProgress tree,workInProgress tree 完成后会替换 current tree。
- 每更新一个节点,同时生成该节点对应的 Effect List。
- 为每个节点创建更新任务。
- 将创建的更新任务加入任务队列,等待调度。
- 调度由 scheduler 模块完成,其核心职责是执行回调。
- scheduler 模块实现了跨平台兼容的 requestIdleCallback。
- 每处理完一个 Fiber Node 的更新,可以中断、挂起,或恢复。
- 根据 Effect List 更新 DOM (commit 阶段)。
- React 会遍历 Effect List 将所有变更一次性更新到 DOM 上。
- 这一阶段的工作会导致用户可见的变化。因此该过程不可中断,必须一直执行直到更新完成。
三、React16版本之前的渲染方式
1、模拟render渲染
//作用:将元素渲染到界面
//参数:element 元素,rootPatent 渲染元素的根节点let element =(<div id="1">I M hero<div>哈哈哈</div></div>
)function render(element,rootParent){//1.创建元素 let dom=docment.createElement(element.type)//2.给元素添加属性Object.keys(element.props).filter(prop=>prop!="children").forEach(v=>dom[v]=element.props[v])//3.将元素的子元素进行渲染(递归)if(Array.isArray(element.props.children)){element.props.children.forEach(c=>render(c,dom))}else{dom.innerHTML=element.props.children;}
}
2、element 元素Balbel编译后的数据结构 ,传入render()供react渲染
{"type": "div","key": null,"ref": null,"props": {"id": "1","children": ["I M hero", {"type": "div","key": null,"ref": null,"props": {"children": "哈哈哈"},"_owner": null,"_store": {}}]},"_owner": null,"_store": {}
}
3、 引发问题
因为如果界面节点多,层次深,递归渲染比较耗时
且 js是单线程的,UI线程和JS线程互斥,会照成界面卡顿,
所以 react在新版本中引入了 fiber的架构模式
4、老的架构方式造成界面掉帧卡顿原因
JS执行js引擎和页面渲染在同一个线程中,GUI渲染和JS执行两者是互斥的,如果某个js任务执行时间过长,浏览器就会推迟渲染,造成页面掉帧(浏览器每个帧都会进行样式计算、布局和绘制操作),页面刷新率低于24fps,形成视觉上的界面卡顿
2、fiber是一个执行单元,每次执行完一个执行单元,Reacta就会检查现在还剩多少时间,如果没有时间就将控制权让出去
四、关于setState是否为异步的解析
1、正常情况下,没有使用组件情况下,是同步更新的
但是不会立即获取到最新的state的值,因为这种情况调用setState只是单纯的将传入的state值放入UpdateQueen这条链表上,未执行更新
但内部会执行一个回调函数,才会真正的更新state,再重新渲染(无法立即获取值)
2、当使用组件时才是真正的异步更新模式,无法立即获取最新的状态,并且在更新和渲染时,会将整个过长放入eventloop中去执行 ,这时候才是真正的异步(无法立即获取值)
3、当使用flushSync()API书写setState时,react更新渲染完全同步,react会立即更新及渲染过程(可以立即获取值)
4、addEventLister()回调中setState(),非合成事件 (可以立即获取值)
5、setState()第二个参数回调函数中读取最新state值
五、fiber如何被打断
在reconciliation 阶段,指创建fiber的过程 :React16将Dom节点打散成了相互独立且有联系的一个个fiber对象,他们之间存在优先级关系,
在渲染时, 通过将一个个fiber任务打散在浏览器渲染的每一帧中 ,而Fiber
实现了自己的组件调用栈,它以链表的形式遍历组件树,可以灵活的暂停、继续和丢弃执行的任务。
实现方式是使用了浏览器的requestIdleCallback
这一 API,可以让浏览器在空闲的时候执行回调,在回调参数中可以获取到当前帧剩余的时间,fiber 利用了这个参数,判断当前剩下的时间是否足够继续执行任务,如果足够则继续执行,否则暂停任务,并调用 requestIdleCallback 通知浏览器下次空闲的时候继续执行当前的任务。
六、(React新版本中)fiber为什么要废弃一些生命周期
在 fiber 中,
更新分为两个阶段,
1、reconciliation(real爱可塞累神=>和解) 的阶段,这个阶段在计算前后 dom 树的差异,耗时长,可以被打断
2、然后是 commit 的阶段,这个阶段将把更新渲染到页面上,一口气把更新渲染到页面上,不会被打断
因此:
reconciliation 的阶段会被打断,可能会导致 commit 前的这些生命周期函数多次执行。react 官方目前已经把
componentWillMount
、componentWillReceiveProps
和componetWillUpdate
标记为 unsafe,并使用新的生命周期函数getDerivedStateFromProps
和getSnapshotBeforeUpdate
进行替换。
mit 前的这些生命周期函数多次执行。react 官方目前已经把 componentWillMount
、componentWillReceiveProps
和 componetWillUpdate
标记为 unsafe,并使用新的生命周期函数 getDerivedStateFromProps
和 getSnapshotBeforeUpdate
进行替换。
React-fiber架构的解释相关推荐
- React系列——React Fiber 架构介绍资料汇总(翻译+中文资料)
原文 react-fiber-architecture 介绍 React Fibre是React核心算法正在进行的重新实现.它是React团队两年多的研究成果. React Fiber的目标是提高其对 ...
- 转载:React Fiber架构(浅显易懂)
性能优化是一个系统性的工程,如果只看到局部,引入算法,当然是越快越好; 但从整体来看,在关键点引入缓存,可以秒杀N多算法,或另辟蹊径,探索事件的本质,可能用户要的并不是快-- React16启用了全新 ...
- React Fiber架构原理剖析
一.概述 在 React 16 之前,VirtualDOM 的更新采用的是Stack架构实现的,也就是循环递归方式.不过,这种对比方式有明显的缺陷,就是一旦任务开始进行就无法中断,如果遇到应用中组件数 ...
- react fiber架构学习
同步更新过程的局限 在v16版本以前,react的更新过程是通过递归从根组件树开始同步进行的,更新过程无法被打断,当组件树很大的时候就会出现卡顿的问题 react中的虚拟dom import Reac ...
- 从0实现react框架,React Fiber架构和Fiber Diff算法
react框架是目前最为流行的前端框架之一,尤其在很多大厂,应用更为广泛.相对于一些mvvm框架,react上手需要一定的技术基础,但掌握后,编码体验和性能是很不错的.react整体思想是函数式编程, ...
- React Fiber架构原理
一,概述 在 React 16 之前,VirtualDOM 的更新过程是采用 Stack 架构实现的,也就是循环递归方式.这种对比方式有一个问题,就是一旦任务开始进行就无法中断,如果应用中组件数量庞大 ...
- react 日期怎么格式化_手写React的Fiber架构,深入理解其原理
熟悉React的朋友都知道,React支持jsx语法,我们可以直接将HTML代码写到JS中间,然后渲染到页面上,我们写的HTML如果有更新的话,React还有虚拟DOM的对比,只更新变化的部分,而不重 ...
- react源码中的fiber架构
先看一下FiberNode在源码中的样子 FiberNode // packages/react-reconciler/src/ReactFiber.old.js function FiberNode ...
- 【React】1077- React Fiber架构浅析
1.浏览器渲染 为了更好的理解 React Fiber, 我们先简单了解下渲染器进程的内部工作原理. 参考资料: 从内部了解现代浏览器(3)[1] 渲染树构建.布局及绘制[2] 1.1 渲染帧 帧 ( ...
- React Fiber 原理介绍
欢迎关注我的公众号睿Talk,获取我最新的文章: 一.前言 在 React Fiber 架构面世一年多后,最近 React 又发布了最新版 16.8.0,又一激动人心的特性:React Hooks 正 ...
最新文章
- 云服务器 架设传奇_传奇手游-战神引擎架设教程
- key的数据类型是字符串
- 内存管理,数据类型的基本使用与基本运算符(python2中与用户交互)
- SpringMVC的数据响应
- 19 删除链表的倒数第N个
- 1787: [Ahoi2008]Meet 紧急集合
- post和get两种提交方式的区别
- python好学么数学_Python难学吗,本人数学和英语都很差,想学,都是兴趣爱好
- Matplotlib 中文用户指南 8.1 屏幕截图
- 为什么java jvm.dll_Windows下java、javaw、javaws以及jvm.dll等进程的区别
- 在线数理思维教育品牌“火花思维”完成4000万美元C轮融资
- gtkterm ubuntu下好用的串口工具使用心得-转
- 磁盘:最容易被忽略的性能洼地
- 【原创】Structure from Motion (SfM)算法测试---3D重建简介
- 小学生学AD16(入门级别,看这篇就够了)
- linux 隐藏命令参数,linux – 在ps中隐藏命令的参数
- 10·24|程序员节!
- Java字符串相似度匹配
- struct2破绽及升级
- 有声电子书成市场新宠 影响人们阅读习惯
热门文章
- HJL-93/AY AC220V数字式交流三相电流继电器
- Protobuf简单使用
- terminate called after throwing an instance of ‘YAML::TypedBadConversion<int>‘ what(): bad conver
- 区块链 以太坊 多层调用,获取调用者 msg.sender
- php k线15分钟 30分钟,成功率极高的“分时K线战法”:15分钟K线战法+30分钟K线战法...
- 智能优化算法:海鸥算法原理及Matlab代码
- 【zz】陈硕:当析构函数遇到多线程──C++ 中线程安全的对象回调
- erlang底层c定时器设计-Erlang源码学习二
- Contest3121 - 2021级新生个人训练赛第26场_问题 F: 乐乐的数字
- win10文件夹加密_Win10 系统优化软件 Windows 10 Manager v3.2.0