本文转载自微信公众号《JS日报》,作者慧慧。转载本文请联系JS每日一问公众号。1.问题JavaScript引擎和页面渲染引擎线程是互斥的。当其中一个线程执行时,另一个线程只能挂起等待。如果JavaScript线程长时间占用主线程,那么渲染层级的更新就无法进行。如果长时间不等待,界面会长时间不更新,导致页面响应不佳,用户可能会感到卡顿。这正是React15的StackReconciler面临的问题。React在渲染组件时,从开始到渲染完成的整个过程是一气呵成的,不能被打断。如果组件很大,js线程会继续执行,然后等到整个VDOM树计算完成后,才交给渲染线程。这将导致一些用户交互和动画。2.什么是反应纤维?这是Facebook在React上花费了两年多时间的一次重大改变和优化。它是对React核心算法的重新实现。Facebook在ReactConf2017会议上确认,ReactFiber在React16版本中发布在React中,主要做了以下操作:为每个任务添加优先级,高优先级的任务可以打断低优先级的任务。然后再试,注意重新执行低优先级的任务会增加异步任务,调用requestIdleCallbackapi,浏览器空闲时执行domdifftree变成链表。一个dom对应两个fiber(一个链表),对应两个Queue,就是找到中断的任务,重新执行。从架构的角度来看,Fiber是对React核心算法(即协调过程)的重写。从编码的角度来看,Fiber是React内部定义的一种数据类型。Structure,即Fiber树结构的节点单元,即React16新架构下的虚拟DOM。Fiber是一个JavaScript对象,它包含元素信息、更新操作队列和元素类型。它的数据结构如下:typeFiber={//用于标记fiber的WorkTag类型,主要表示当前fiber代表的组件类型,如FunctionComponent、ClassComponent等。第一个参数elementType:any,//Theresolvedfunction/class/associatedwiththisfiber.//表示当前表示的节点类型type:any,//表示当前FiberNode对应的元素组件实例stateNode:any,//指向他在Fiber节点树中的`parent`使用处理完这个节点向上返回return:Fiber|null,//指向它的第一个子节点child:Fiber|null,//指向自己的兄弟结构,兄弟节点的返回指向同一个父节点sibling:fiber|null,index:number,ref:null|(((handle:mixed)=>void)&{_stringRef:?string})|RefObject,//当前处理过程中的组件propsObjectpendingProps:any,//上次渲染完成后的propsmemoizedProps:any,//生成的UpdateFiber对应的组件会存储在这个队列中updateQueue:UpdateQueue<any>|null,//statememoizedStateatthetimeoflastrendering:any,//一个列表,用来存放这个Fiber所依赖的contextfirstContextDependency:ContextDependency
