关于前端:react中的渲染流程

2次阅读

共计 2218 个字符,预计需要花费 6 分钟才能阅读完成。

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

fiber
咱们能够通过某些调度策略正当调配 CPU 资源,从而进步用户的响应速度
通过 Fiber 架构,让本人的和谐过程变成可被中断。适时地让出 CPU 执行权,除了能够让浏览器及时地响应用户的交互
渲染分三个阶段:Scheduler 调度,Reconciler 和谐,commit 提交

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();
正文完
 0