-
Notifications
You must be signed in to change notification settings - Fork 2
Open
Labels
note简单笔记简单笔记
Description
1. 遍历 Fiber Tree 时的优化
react每产生一个更新, 都会遍历整个Fiber Tree, 这样做会产生很大的性能开销, 所以就需要采取必要的优化措施.
在 beginWork 方法内部, 分别进行了两个方面的优化:
- props 是否改变?
if (oldProps !== newProps || hasLegacyContextChanged()) {
// If props or context changed, mark the fiber as having performed work.
// This may be unset if the props are determined to be equal later (memo).
didReceiveUpdate = true;
}react通过比对当前遍历到的fiber节点的新旧props是否相等, 来计算当前节点是否需要在当前的更新批次中更新.
- 当前节点是否有挂起的更新?
else if (updateExpirationTime < renderExpirationTime) {
didReceiveUpdate = false;
return bailoutOnAlreadyFinishedWork(
current,
workInProgress,
renderExpirationTime,
);
}如果当前的fiber节点产生的更新的优先级小于当前整体更新流程的优先级, 代表当前节点不需要更新, 继续检查当前节点的子树是否需要更新.
- 当前节点的子树有否有挂起的更新
function bailoutOnAlreadyFinishedWork(
current: Fiber | null,
workInProgress: Fiber,
renderExpirationTime: ExpirationTime,
): Fiber | null {
// Check if the children have any pending work.
const childExpirationTime = workInProgress.childExpirationTime;
if (childExpirationTime < renderExpirationTime) {
// The children don't 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 doesn't have work, but its subtree does. Clone the child
// fibers and continue.
cloneChildFibers(current, workInProgress);
return workInProgress.child;
}
}在bailoutOnAlreadyFinishedWork内部, 会检查当前fiber节点的子树是否有挂起的更新:
- 如果没有, 或者子树的更新优先级较小: 终止当前的整体遍历流程
- 反之: 克隆其子树, 复用节点
Metadata
Metadata
Assignees
Labels
note简单笔记简单笔记