当前位置: 首页 > news >正文

嘉兴网站建设运营网题 做问卷的网站

嘉兴网站建设运营,网题 做问卷的网站,商标设计网址大全,中国移动官方官网beginWork 1 #xff09;概述 在 renderRoot 之后#xff0c;要对我们的 Fiber 树每一个节点进行对应的更新更新节点的一个入口方法#xff0c;就是 beginWork这个入口方法会有帮助我们去优化整棵树的更新过程 react 它的节点其实是非常多的#xff0c;如果每一次子节点的…beginWork 1 概述 在 renderRoot 之后要对我们的 Fiber 树每一个节点进行对应的更新更新节点的一个入口方法就是 beginWork这个入口方法会有帮助我们去优化整棵树的更新过程 react 它的节点其实是非常多的如果每一次子节点的一个更新就需要每一个节点都执行一遍更新的话它整体的性能肯定会不好而且是没有必要的我们一个子节点的更新可能不会影响到它的兄弟节点的更新所以这部分肯定是要优化的 具体它是如何进行优化的如下 首先要判断组件的更新是否可以优化然后要根据节点的类型分发进行处理每一个节点它的更新方式会不一样最后是要根据 expirationTime 等信息判断这个节点的更新是否可以跳过 2 源码 在 renderRoot 中它里面调用一个方法叫做 workLoop在 workLoop 中调用的一个方法叫做 performUnitOfWork而 beginWork 方法就在 performUnitOfWork 中调用beginWork 就是执行对整棵树的每一个节点进行更新的一个操作beginWork 来自于import {beginWork} from ./ReactFiberBeginWork;定位到 packages/react-reconciler/src/ReactFiberBeginWork.js 整个文件 export 出去的只有 beginWork 方法 function beginWork(current: Fiber | null,workInProgress: Fiber,renderExpirationTime: ExpirationTime, ): Fiber | null {// 读取了 workInProgress.expirationTime 这个值这个 expirationTime 是节点上的 expirationTime// 函数第三个参数 renderExpirationTime 是 nextExpirationTimeToWorkOn 和 下面这个 expirationTime 有区别const updateExpirationTime workInProgress.expirationTime;// 在 ReactDOM.render 第一次渲染时第一个节点 current 是有值的, 接下去的节点都是没有的// 因为我们操作都是在 workInProgress 上操作的// 所以workInProgress 创建的 child 节点也是一个 workInProgress 而不是 current// performUnitOfWork 接收的就是 workInProgressif (current ! null) {const oldProps current.memoizedProps;const newProps workInProgress.pendingProps;// 下面 renderExpirationTime 标志优先级最大都到哪个点如果节点上的 expirationTime 比 renderExpirationTime 小// 说明节点上有优先级更高的任务在这次渲染里是会执行的反之则不需要进行渲染这个节点可以跳过// (updateExpirationTime NoWork || updateExpirationTime renderExpirationTime) 代表没有更新 或 有更新但是优先级不高// hasLegacyContextChanged 属 context 相关api, childContextType 先跳过// oldProps newProps 表示 props 一样if (oldProps newProps !hasLegacyContextChanged() (updateExpirationTime NoWork ||updateExpirationTime renderExpirationTime)) {// This fiber does not have any pending work. Bailout without entering// the begin phase. Theres still some bookkeeping we that needs to be done// in this optimized path, mostly pushing stuff onto the stack.// switch 先跳过switch (workInProgress.tag) {case HostRoot:pushHostRootContext(workInProgress);resetHydrationState();break;case HostComponent:pushHostContext(workInProgress);break;case ClassComponent: {const Component workInProgress.type;if (isLegacyContextProvider(Component)) {pushLegacyContextProvider(workInProgress);}break;}case HostPortal:pushHostContainer(workInProgress,workInProgress.stateNode.containerInfo,);break;case ContextProvider: {const newValue workInProgress.memoizedProps.value;pushProvider(workInProgress, newValue);break;}case Profiler:if (enableProfilerTimer) {workInProgress.effectTag | Update;}break;case SuspenseComponent: {const state: SuspenseState | null workInProgress.memoizedState;const didTimeout state ! null state.didTimeout;if (didTimeout) {// If this boundary is currently timed out, we need to decide// whether to retry the primary children, or to skip over it and// go straight to the fallback. Check the priority of the primary// child fragment.const primaryChildFragment: Fiber (workInProgress.child: any);const primaryChildExpirationTime primaryChildFragment.childExpirationTime;if (primaryChildExpirationTime ! NoWork primaryChildExpirationTime renderExpirationTime) {// The primary children have pending work. Use the normal path// to attempt to render the primary children again.return updateSuspenseComponent(current,workInProgress,renderExpirationTime,);} else {// The primary children do not have pending work with sufficient// priority. Bailout.const child bailoutOnAlreadyFinishedWork(current,workInProgress,renderExpirationTime,);if (child ! null) {// The fallback children have pending work. Skip over the// primary children and work on the fallback.return child.sibling;} else {return null;}}}break;}}// 这个方法跳过该节点与其所有子节点的更新return bailoutOnAlreadyFinishedWork(current,workInProgress,renderExpirationTime,);}}// Before entering the begin phase, clear the expiration time.workInProgress.expirationTime NoWork;// 如果节点有更新通过节点的 tag执行不同的方法进行组件的更新switch (workInProgress.tag) {case IndeterminateComponent: {const elementType workInProgress.elementType;return mountIndeterminateComponent(current,workInProgress,elementType,renderExpirationTime,);}case LazyComponent: {const elementType workInProgress.elementType;return mountLazyComponent(current,workInProgress,elementType,updateExpirationTime,renderExpirationTime,);}case FunctionComponent: {const Component workInProgress.type;const unresolvedProps workInProgress.pendingProps;const resolvedProps workInProgress.elementType Component? unresolvedProps: resolveDefaultProps(Component, unresolvedProps);return updateFunctionComponent(current,workInProgress,Component,resolvedProps,renderExpirationTime,);}case ClassComponent: {const Component workInProgress.type;const unresolvedProps workInProgress.pendingProps;const resolvedProps workInProgress.elementType Component? unresolvedProps: resolveDefaultProps(Component, unresolvedProps);return updateClassComponent(current,workInProgress,Component,resolvedProps,renderExpirationTime,);}case HostRoot:return updateHostRoot(current, workInProgress, renderExpirationTime);case HostComponent:return updateHostComponent(current, workInProgress, renderExpirationTime);case HostText:return updateHostText(current, workInProgress);case SuspenseComponent:return updateSuspenseComponent(current,workInProgress,renderExpirationTime,);case HostPortal:return updatePortalComponent(current,workInProgress,renderExpirationTime,);case ForwardRef: {const type workInProgress.type;const unresolvedProps workInProgress.pendingProps;const resolvedProps workInProgress.elementType type? unresolvedProps: resolveDefaultProps(type, unresolvedProps);return updateForwardRef(current,workInProgress,type,resolvedProps,renderExpirationTime,);}case Fragment:return updateFragment(current, workInProgress, renderExpirationTime);case Mode:return updateMode(current, workInProgress, renderExpirationTime);case Profiler:return updateProfiler(current, workInProgress, renderExpirationTime);case ContextProvider:return updateContextProvider(current,workInProgress,renderExpirationTime,);case ContextConsumer:return updateContextConsumer(current,workInProgress,renderExpirationTime,);case MemoComponent: {const type workInProgress.type;const unresolvedProps workInProgress.pendingProps;const resolvedProps resolveDefaultProps(type.type, unresolvedProps);return updateMemoComponent(current,workInProgress,type,resolvedProps,updateExpirationTime,renderExpirationTime,);}case SimpleMemoComponent: {return updateSimpleMemoComponent(current,workInProgress,workInProgress.type,workInProgress.pendingProps,updateExpirationTime,renderExpirationTime,);}case IncompleteClassComponent: {const Component workInProgress.type;const unresolvedProps workInProgress.pendingProps;const resolvedProps workInProgress.elementType Component? unresolvedProps: resolveDefaultProps(Component, unresolvedProps);return mountIncompleteClassComponent(current,workInProgress,Component,resolvedProps,renderExpirationTime,);}default:invariant(false,Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue.,);} }注意最顶层 workInProgress.expirationTime; 这个 expirationTime Fiber 节点上的 expirationTime 对比 ReactFiberScheduler.js 中的 renderRoot 中读取的 root.nextExpirationTimeToWorkOn这个 root 是 FiberRoot, 而 FiberRoot 对应的 Fiber对象是 RootFiberRootFiber 是 FiberRoot 的 current 属性它没有对应React组件树的任何节点, 它只对应 FiberRoot 节点 FiberRoot 节点也就是挂载整个应用到的 Dom 节点FiberRoot 上面存储整个应用的 expirationTime 和 RootFiber 的 stateNode 属性是 FiberRootFiberRoot 上面会存储整个应用上面的 expirationTime 和 nextExpirationTimeToWorkOn上面的两个值意义是不一样的, 在 renderRoot 函数中的一段代码如下// Reset the stack and start working from the root. resetStack(); nextRoot root; nextRenderExpirationTime expirationTime; // nextUnitOfWork 是一个Fiber对象, 对应 RootFiber, 而非 FiberRoot // 更新过程使用的都是 Fiber 对象不会是 FiberRoot nextUnitOfWork createWorkInProgress(nextRoot.current, // 注意这里null,nextRenderExpirationTime, );nextUnitOfWork 才是我们每一个节点去更新时要操作的节点对象 所以workInProgress.expirationTime 是对应Fiber节点产生更新的过期时间 这里页面点击按钮让某个组件更新最多到App上面创建更新不可能到 RootFiber 上面创建更新 而 RootFiber 产生更新时在 ReactDOM.render 的时候才会有注意在 beginWork 第一个参数是 current 是 Fiber对象它对应的tag是 HostRoot 在创建 FibeRoot 时, 在 ReactFiberReconciler.js 中的 createContainer 中有一个方法叫做 createFiberRoot, 定位到 ReactFiberRoot.js 中定位到 createHostRootFiber 方法而这个方法又来自于 ReactFiber.js找到 createFiber, 是最终创建Fiber对象的时候调用的方法return createFiber(HostRoot, null, null, mode);参数是 HostRoot, null, null, mode第一个参数 HostRoot 就是 Fiber的tag 在 ReactFiberScheduler.js 中 performUnitOfWork 接收的就是一个 workInProgress 它传给 beginWork 的第一个参数 current 是 workInProgress.alternate在第一次渲染也就是 ReactDOM.render 的时候, workInProgress 是刚刚创建的是不会在创建一个 current, 要等渲染结束后把 current 和 workInProgress 的指针进行一个调换它才会变成有 current, 没有 workInProgress再下次有更新产生进行渲染时才会创建一个新的 workInProgress这时候current 和 workInProgress 都有了在最顶层 判断 current 是否 为 null, 也就是 判断是否是第一次渲染 关于 bailoutOnAlreadyFinishedWork 这个方法帮助跳过该节点与其所有子节点的更新function bailoutOnAlreadyFinishedWork(current: Fiber | null,workInProgress: Fiber,renderExpirationTime: ExpirationTime, ): Fiber | null {cancelWorkTimer(workInProgress);if (current ! null) {// Reuse previous context listworkInProgress.firstContextDependency current.firstContextDependency;}if (enableProfilerTimer) {// Dont update base render times for bailouts.stopProfilerTimerIfRunning(workInProgress);}// Check if the children have any pending work.const childExpirationTime workInProgress.childExpirationTime; // 这个值是 React 16.5 加上的更早跳过更新// 子树上无更新或高优先级任务在这次渲染中完成的 则跳过是一个非常大的优化if (childExpirationTime NoWork ||childExpirationTime renderExpirationTime) {// The children dont have any work either. We can skip them.// TODO: Once we add back resuming, we should check if the children are// a work-in-progress set. If so, we need to transfer their effects.return null;} else {// This fiber doesnt have work, but its subtree does. Clone the child// fibers and continue.// 如果子树上有更新要执行拷贝老的childcloneChildFibers(current, workInProgress);return workInProgress.child;} }回过头看 performUnitOfWork, return 了 child 之后赋值给nextlet next; if (enableProfilerTimer) {// ... 跳过很多代码next beginWork(current, workInProgress, nextRenderExpirationTime);// ... 跳过很多代码 } else {next beginWork(current, workInProgress, nextRenderExpirationTime);workInProgress.memoizedProps workInProgress.pendingProps; }// ... 跳过很多代码if (next null) {// If this doesnt spawn new work, complete the current work.next completeUnitOfWork(workInProgress); }ReactCurrentOwner.current null; // next 不为 null, 直接 return return next;return next; 之后 回调 workLoop, 之后赋值给 nextUnitOfWorkwhile (nextUnitOfWork ! null) {nextUnitOfWork performUnitOfWork(nextUnitOfWork);}通过 while 循环继续执行 child 的更新这就是循环能够成立的条件 回到 beginWork 中当节点还有更新的时候执行 switch case 通过节点类型执行不同的方法来进行组件的更新比如 FunctionComponent, MemoComponent 等
文章转载自:
http://www.morning.lskyz.cn.gov.cn.lskyz.cn
http://www.morning.xplng.cn.gov.cn.xplng.cn
http://www.morning.rdymd.cn.gov.cn.rdymd.cn
http://www.morning.tkxr.cn.gov.cn.tkxr.cn
http://www.morning.ndmbz.cn.gov.cn.ndmbz.cn
http://www.morning.zlxkp.cn.gov.cn.zlxkp.cn
http://www.morning.nxbsq.cn.gov.cn.nxbsq.cn
http://www.morning.bpmdn.cn.gov.cn.bpmdn.cn
http://www.morning.jqmqf.cn.gov.cn.jqmqf.cn
http://www.morning.zbnts.cn.gov.cn.zbnts.cn
http://www.morning.fthcn.cn.gov.cn.fthcn.cn
http://www.morning.rfmzs.cn.gov.cn.rfmzs.cn
http://www.morning.wkpfm.cn.gov.cn.wkpfm.cn
http://www.morning.hjrjy.cn.gov.cn.hjrjy.cn
http://www.morning.gnzsd.cn.gov.cn.gnzsd.cn
http://www.morning.rszyf.cn.gov.cn.rszyf.cn
http://www.morning.ykklw.cn.gov.cn.ykklw.cn
http://www.morning.wjyyg.cn.gov.cn.wjyyg.cn
http://www.morning.fwmln.cn.gov.cn.fwmln.cn
http://www.morning.nypgb.cn.gov.cn.nypgb.cn
http://www.morning.xfjwm.cn.gov.cn.xfjwm.cn
http://www.morning.ymmjx.cn.gov.cn.ymmjx.cn
http://www.morning.ktskc.cn.gov.cn.ktskc.cn
http://www.morning.xxgfl.cn.gov.cn.xxgfl.cn
http://www.morning.btqqh.cn.gov.cn.btqqh.cn
http://www.morning.rkjb.cn.gov.cn.rkjb.cn
http://www.morning.hnrdtz.com.gov.cn.hnrdtz.com
http://www.morning.cjcry.cn.gov.cn.cjcry.cn
http://www.morning.qjlkp.cn.gov.cn.qjlkp.cn
http://www.morning.dfygx.cn.gov.cn.dfygx.cn
http://www.morning.gnzsd.cn.gov.cn.gnzsd.cn
http://www.morning.qyxnf.cn.gov.cn.qyxnf.cn
http://www.morning.jzkqg.cn.gov.cn.jzkqg.cn
http://www.morning.xzkgp.cn.gov.cn.xzkgp.cn
http://www.morning.zfhzx.cn.gov.cn.zfhzx.cn
http://www.morning.fyskq.cn.gov.cn.fyskq.cn
http://www.morning.gbfzy.cn.gov.cn.gbfzy.cn
http://www.morning.bzkgn.cn.gov.cn.bzkgn.cn
http://www.morning.tjqcfw.cn.gov.cn.tjqcfw.cn
http://www.morning.yrnyz.cn.gov.cn.yrnyz.cn
http://www.morning.wjlhp.cn.gov.cn.wjlhp.cn
http://www.morning.kqgqy.cn.gov.cn.kqgqy.cn
http://www.morning.qrqcr.cn.gov.cn.qrqcr.cn
http://www.morning.nyqnk.cn.gov.cn.nyqnk.cn
http://www.morning.mqxzh.cn.gov.cn.mqxzh.cn
http://www.morning.grbp.cn.gov.cn.grbp.cn
http://www.morning.wqmpd.cn.gov.cn.wqmpd.cn
http://www.morning.yubkwd.cn.gov.cn.yubkwd.cn
http://www.morning.ktmpw.cn.gov.cn.ktmpw.cn
http://www.morning.zpjhh.cn.gov.cn.zpjhh.cn
http://www.morning.hffjj.cn.gov.cn.hffjj.cn
http://www.morning.ckbmz.cn.gov.cn.ckbmz.cn
http://www.morning.cbnxq.cn.gov.cn.cbnxq.cn
http://www.morning.jcxgr.cn.gov.cn.jcxgr.cn
http://www.morning.mzrqj.cn.gov.cn.mzrqj.cn
http://www.morning.lmmh.cn.gov.cn.lmmh.cn
http://www.morning.gthgf.cn.gov.cn.gthgf.cn
http://www.morning.btrfm.cn.gov.cn.btrfm.cn
http://www.morning.plgbh.cn.gov.cn.plgbh.cn
http://www.morning.lmxrt.cn.gov.cn.lmxrt.cn
http://www.morning.mpscg.cn.gov.cn.mpscg.cn
http://www.morning.znlhc.cn.gov.cn.znlhc.cn
http://www.morning.jcwhk.cn.gov.cn.jcwhk.cn
http://www.morning.sbwr.cn.gov.cn.sbwr.cn
http://www.morning.prkdl.cn.gov.cn.prkdl.cn
http://www.morning.bpmtz.cn.gov.cn.bpmtz.cn
http://www.morning.jnrry.cn.gov.cn.jnrry.cn
http://www.morning.nchlk.cn.gov.cn.nchlk.cn
http://www.morning.qkcyk.cn.gov.cn.qkcyk.cn
http://www.morning.nmtyx.cn.gov.cn.nmtyx.cn
http://www.morning.lnckq.cn.gov.cn.lnckq.cn
http://www.morning.bgxgq.cn.gov.cn.bgxgq.cn
http://www.morning.lstmq.cn.gov.cn.lstmq.cn
http://www.morning.dqdss.cn.gov.cn.dqdss.cn
http://www.morning.qrdkk.cn.gov.cn.qrdkk.cn
http://www.morning.nyfyq.cn.gov.cn.nyfyq.cn
http://www.morning.psxcr.cn.gov.cn.psxcr.cn
http://www.morning.pqbkk.cn.gov.cn.pqbkk.cn
http://www.morning.ydwnc.cn.gov.cn.ydwnc.cn
http://www.morning.lxqkt.cn.gov.cn.lxqkt.cn
http://www.tj-hxxt.cn/news/247722.html

相关文章:

  • 做网站的把网站写成一行企业网站建设熊掌号
  • 专业做网站厂家广告设计介绍
  • 免费手机网站空间申请三杰网站建设
  • 没有rss源的网站如何做rss订阅宁波网络推广联系方式
  • 商洛网站建设电话iis添加网站无法访问
  • 做好网站建设深圳专业建网站多少钱
  • 重庆技术网站建设中国的网站域名是什么
  • wordpress更改站点ps课堂网站
  • 青岛网站有限公司太原做企业网站的
  • 请问网上有没有比较好的网站可以做照片书的呀?要求质量比较好的!网站设计方案及报价单
  • 湖南专业外贸建站公司建设银行报网站
  • 郑州网站建设价位自己怎么学电商运营
  • 合肥seo网站优化国外外贸网站大全
  • 舟山市网站建设如何开拓海外市场
  • 功能性质网站有哪些网站wordpress设置专题页
  • 建设银行 福州招聘网站南京理工大学电子工程网官网
  • 企业网站底部河南建设工程信息网官网首页
  • 海口网站建设美丽湖北网站推广服务
  • 台州小型网站建设上市公司协会网站建设汇报
  • 做网站必须用对方服务器邻水网站建设
  • 营销型网站制作msggwordpress page 分页
  • 保险资料网站有哪些编程培训机构名字
  • 云南昆明网站建设价格不会写代码怎么做网站
  • 网站投票怎么做中国建设银行的官方网址
  • 天长网站制作网站建设与管理ppt模板下载
  • 济南市个人网站制作微淘客网站建设
  • 商城网站后续费用湖南郴州
  • wordpress绑定两个域名seo费用
  • 网站文章系统wordpress的小工具怎么用
  • 网站宣传内容wordpress+move插件