大家好,我是前端西瓜哥。为了提升React的性能,React团队在开发React16时做了一次底层重构,引入了ReactFiber的概念。什么是反应纤维?Fiber,原意为“光纤”,在计算机世界中就是“光纤”的意思。Fiber可以看作协程的一种,是一种任务调度的方式。JavaScript是单线程的,有事件循环的概念。它有一个有优先级的任务队列,只能按顺序执行一个任务。它不支持同时执行多个任务。这样设计的好处是不需要考虑多线程带来的顺序问题,为锁做一些额外的逻辑来保证执行顺序符合预期。但是由于无法使用并行能力,在CPU密集型场景下会出现性能问题。例如,一个任务耗时过长,会引起其他任务,导致用户交互响应延迟。React组件更新是一个CPU密集型操作,因为需要比较新旧虚拟DOM树(diff,React中的Reconciliation负责),找出需要更新的内容(patch),更新真正的通过打补丁的DOM树(React中的渲染器负责)。当需要比较的组件树很多时,会发生大量的新旧节点比较,CPU会占用大量时间。当耗时超过16.6ms(每秒60帧的基准)时,用户会感觉到明显的卡顿。这一系列操作是递归实现的,是同步的,不可中断的。因为一旦中断,调用栈就会被破坏,中间状态就会丢失。这种基于调用堆栈的实现称为StackReconciliation。React16的一项关键任务是在更新组件时优化大量CPU计算。最后,我们选择了使用“时间分片”的方案,即将应该在同一时间完成的工作拆分成异步任务。执行的时间。这种新架构称为FiberReconciliation。在React中,Fiber模拟了之前的递归调用,具体是通过一个链表来模拟函数的调用栈,使得调用可以中断,将一个大的更新任务拆分成小任务,并设置优先级。在浏览器空闲时异步执行。在FiberNode之前,我们提到过链表的遍历是用来模拟递归栈调用的,而链表的节点React就是用FiberNode来表示的。FiberNode其实是一个虚拟的DOM,记录了:节点相关的类型,比如tag表示组件类型,type表示元素类型等。节点的指向。与副作用相关的属性。车道是关于调度优先级的。functionFiberNode(tag:WorkTag,pendingProps:mixed,key:null|string,mode:TypeOfMode,){//实例this.tag=tag;//组件类型,例如Function/Class/Hostthis.key=key;//key唯一值,通常在列表中使用this.elementType=null;this.type=null;//元素类型,字符串或者类或者函数,比如"div"/ComponentFn/Classthis.stateNode=null;//指向真正的DOM对象//Fiberthis.return=null;//父光纤this.child=null;//孩子的第一个this.siblingFiber=null;//下一个兄弟节点this.index=0;//在兄弟节点中的位置this.ref=null;this.pendingProps=pendingProps;this.memoizedProps=null;this.updateQueue=null;this.memoizedState=null;this.dependencies=null;this.mode=模式;//效果this.flags=NoFlags;this.subtreeFlags=NoFlags;这个。删除=空;this.lanes=NoLanes;this.childLanes=NoLanes;this.alternate=null;//...}Fiberviareturn指向父Fiber,child指向子Fiber的头部,sibling指向下一个兄弟节点。通过它们我们其实可以得到一个完整的结构树。for:functionApp(){return(
