快速响应:异步可中断 + 增量更新(不是全量更新)
性能瓶颈
JS任务执行时间过长。浏览器刷新频率为60Hz大概16.6毫秒渲染一次,而JS线程和渲染线程是互斥的,所以如果JS线程执行任务时间超过16.6ms的话,就会导致掉帧,导致卡顿,
解决方案就是React利用空闲的时间进行更新,不影响渲染进行的渲染把一个耗时任务切分成一个个小任务,分布在每一帧里的方式就叫时间切片(5ms-5.5ms)
react为了兼容性,没有用requestIdleCallback 而是使用MessageChannel+requestAnimationFrame模拟了requestIdleCallback

fiber
我们可以通过某些调度策略合理分配CPU资源,从而提高用户的响应速度
通过Fiber架构,让自己的调和过程变成可被中断。 适时地让出CPU执行权,除了可以让浏览器及时地响应用户的交互
渲染分三个阶段:Scheduler调度,Reconciler调和,commit提交
image.png
Fiber对象

let workInProgress;
const TAG_ROOT ='TAG ROOT';
//根Fiber
let rootFiber = {
    tag:TAG_ROOT,
    key:"ROOT",
    stateNode:root, //真实Dom节点
    props:{children:[A]}
}

//这个Fiber根节点const TAG_HOST =TAG_HOST';//指的是原生DOM节点 div span pfunction
workLoop(deadline){
 while(deadline.timeRemainidng()>1&&workInProgress){//如果有任务就执行 
          workInProgress=performUnitofWork(workInProgress)
   }
}
function performUnitofwork(workInProgress){
   beginWork(workInProgress)
   if(workInProgress.child){
     return workInProgress.child
   }
   while(workInProgress){
        completeUnitofWork(workInProgress)
        //没有儿子找兄弟
        if(workInProgresss.sibling){
            retrun workInProgresss.sibling
        }
        //没有兄弟找父亲的兄弟
        workInProgresss = workInProgresss.return
        //没有父亲,就结束了
   }
}
//节点完成
function completeUnitofWork(workInProgress){
    console.log(' completeUnitofwork',workInProgress .key);
    let stateNode;// 真实DOM
    switch(workInProgress.tag)(
         case TAG HOST:
         stateNode = createStateNode(workInProgress);
          break;
}
//创建真实dom元素
function createStateNode(fiber){
  if(fiber.tag === TAG_HOST){
      let stateNode = document.createElement(fiber .type)
      fiber.stateNode = stateNode ;
   }
   return fiber.stateNode;
}
function beginWork(workInProgress){
    console.log( ' beginwork',workInProgress .key);
    let nextChildren =  workInProgress.props.children;
    return  reconcileChildren(workInProgress,nextChildren)
};
//建立链表,根据父fiber和子虚拟DOM数组,构建当前returnFiber的子Fiber树
function reconcileChildren(returnFiber,nextChildren){
   let previousNewFiber;
   let firstChildFiber;
   for(let newIndex=0;newIndex<nextChildren.length;newIndex++){
     let newFiber = createFiber(nextChildren[newIndex]);
     newFiber.return = returnFiber
     if(!firstChildFiber){
        firstChildFiber = newFiber//赋值大儿子
     }else{
        previousNewFiber.sibling = newFiber 
     }
      previousNewFiber = newFiber
   }
    returnFiber.child = firstChildFiber
    return firstChildFiber//返回大儿子
}
function createFiber(element){
  return{
     tag:TAG_HOST,
     type:element.type,
     key:element.key,
     props:element.props
  }
 }
//当前正在执行的工作单元
workInProgress=rootFiber;
workLoop();

ohoherror
21 声望1 粉丝

下一篇 »
手写promise