Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

渲染流程 (函数) #18

Open
yangdui opened this issue May 16, 2020 · 0 comments
Open

渲染流程 (函数) #18

yangdui opened this issue May 16, 2020 · 0 comments

Comments

@yangdui
Copy link
Owner

yangdui commented May 16, 2020

渲染流程 (函数)

updateContainer

computeExpirationForFiber

计算过期时间

scheduleRootUpdate

createUpdate

创建更新对象(一个简单的对象):

{
  expirationTime: expirationTime,

  tag: UpdateState,
  payload: null,
  callback: null,

  next: null,
  nextEffect: null,
}

enqueueUpdate ? 参数 fiber 的确认

更新队列。分为首次渲染、第一次更新、两次以上更新。

如果是首次渲染:创建一个值为空的queue1,然后将 update插入queue1中,其中 current 是 rootFiber

如果是第一次更新:current 是引发更新的 fiber,第一次更新还是没有 alternate ,步骤和首次渲染一样。

如果是第二次更新:有 alternate , 进入:

 if (queue1.lastUpdate === null || queue2.lastUpdate === null)

:如果是首次渲染,enqueueUpdate 第一个参数是 rootFiber,如果是通过 setState 更新,奇数次更新时,第一个参数(fiber)是 current,偶数次更新第一个参数是上次的 workInProgress

scheduleWork

scheduleWorkToRoot

找到当前 fiber 的 root

markPendingPriorityLevel

更新 root 的 earliestPendingTime (最高优先级)和 latestPendingTime (最低优先级)(后面没有用到)

findNextExpirationTimeToWorkOn

涉及到 suspense 组件。expirationTimenextExpirationTimeToWorkOn 区别是:

此时的 expirationTime 是表示当前 fiber 任务的优先级,nextExpirationTimeToWorkOn 是下一次执行更新的时间(判断每个 fiber 是否要执行:findNextExpirationTimeToWorkOn 函数中通过比较 expirationTimenextExpirationTimeToWorkOn 大小,确定 nextExpirationTimeToWorkOn 值。如果在下次执行前没有异步打断的情况,那么执行 nextExpirationTimeToWorkOn (任务优先级最高的任务))。

requestWork

不考虑 earliestSuspendedTimerequestWork 函数的第二个参数是 nextExpirationTimeToWorkOn

addRootToSchedule

添加 root 到 schedule 或者更新 root.expirationTime

performWork

findHighestPriorityRoot
找到优先级更高的 root

performWorkOnRoot

如果有 finishedWork ,直接 completeRoot(有finishedWork ,表明生成好了 fiber 树,一般是上一帧生成好,异步打断没有时间提交 )。

renderRoot

if (expirationTime !== nextRenderExpirationTime || root !== nextRoot || nextUnitOfWork === null)

上面的 if 语句表明:都需要将更新的状态复原以及创建新的 workInProgress

expirationTime !== nextRenderExpirationTime 表明之前有异步任务中断时有更高优先级任务进来。

root !== nextRoot 表明之前异步任务中断时候,更高优先级任务进来并且该 fiber 的 root 不是同一个。

创建一个新的 nextUnitWorkworkInProcess)。

workLoop

循环创建 fiber(后面重点分析)

completeRoot

如果 finishedWork 有值,执行 completeRoot 函数

commitRoot

注意几个 while 循环

commit 结束之后,回到 performWork 函数中继续 while 循环,如果还有其他 root 需要更新的话,继续performWorkOnRoot 函数

workLoop

深度优先,当一侧遍历完后,执行 completeUnitOfWork 函数。在 completeUnitOfWork 函数中,如果有兄弟元素,则返回兄弟元素。

performUnitOfWork

beginWork

如果当前fiber不需要更新:

if (updateExpirationTime < renderExpirationTime)

采用 bailoutOnAlreadyFinishedWork 函数

bailoutOnAlreadyFinishedWork

如果当前节点的子元素有更新(if (childExpirationTime < renderExpirationTime)),则返回相应的子元素(需要逐层返回比较),否则返回 null

beginWork函数后面一个 while 循环中,根据 tag 不同调用不同的函数,其中对于函数组件而言,第一次渲染是选择IndeterminateComponent 标签,更新才是 FunctionComponent。这些函数作用是相同的:都是完成fiber更新以及返回需要更新的子元素

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant