diff --git a/packages/react-reconciler/src/ReactFiber.new.js b/packages/react-reconciler/src/ReactFiber.new.js index eca759ceaba6e..c157958363123 100644 --- a/packages/react-reconciler/src/ReactFiber.new.js +++ b/packages/react-reconciler/src/ReactFiber.new.js @@ -293,6 +293,10 @@ export function createWorkInProgress(current: Fiber, pendingProps: any): Fiber { // But works for yielding (the common case) and should support resuming. workInProgress.actualDuration = 0; workInProgress.actualStartTime = -1; + + // Reset treeBaseDuration when cloning. + // As each child completes rendering, its base durations will bubble up to the parent. + workInProgress.treeBaseDuration = 0; } } @@ -323,11 +327,6 @@ export function createWorkInProgress(current: Fiber, pendingProps: any): Fiber { workInProgress.index = current.index; workInProgress.ref = current.ref; - if (enableProfilerTimer) { - workInProgress.selfBaseDuration = current.selfBaseDuration; - workInProgress.treeBaseDuration = current.treeBaseDuration; - } - if (__DEV__) { workInProgress._debugNeedsRemount = current._debugNeedsRemount; switch (workInProgress.tag) { @@ -381,8 +380,8 @@ export function resetWorkInProgress(workInProgress: Fiber, renderLanes: Lanes) { workInProgress.stateNode = null; if (enableProfilerTimer) { - // Note: We don't reset the actualTime counts. It's useful to accumulate - // actual time across multiple render passes. + // Note: We don't reset the actualTime counts. + // It's useful to accumulate actual time across multiple render passes. workInProgress.selfBaseDuration = 0; workInProgress.treeBaseDuration = 0; } @@ -412,10 +411,10 @@ export function resetWorkInProgress(workInProgress: Fiber, renderLanes: Lanes) { }; if (enableProfilerTimer) { - // Note: We don't reset the actualTime counts. It's useful to accumulate - // actual time across multiple render passes. - workInProgress.selfBaseDuration = current.selfBaseDuration; - workInProgress.treeBaseDuration = current.treeBaseDuration; + // Note: We don't reset the actualTime counts. + // It's useful to accumulate actual time across multiple render passes. + workInProgress.selfBaseDuration = 0; + workInProgress.treeBaseDuration = 0; } } diff --git a/packages/react-reconciler/src/ReactFiberBeginWork.new.js b/packages/react-reconciler/src/ReactFiberBeginWork.new.js index fa27d3dcad74e..15f8ed9e804b5 100644 --- a/packages/react-reconciler/src/ReactFiberBeginWork.new.js +++ b/packages/react-reconciler/src/ReactFiberBeginWork.new.js @@ -1714,6 +1714,15 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { renderLanes, ) ) { + if (enableProfilerTimer) { + if ((workInProgress.mode & ProfileMode) !== NoMode) { + if (current !== null) { + // TODO (effects) Document + workInProgress.actualDuration = current.actualDuration; + } + } + } + // Something in this boundary's subtree already suspended. Switch to // rendering the fallback children. showFallback = true; @@ -1990,10 +1999,9 @@ function mountSuspenseFallbackChildren( primaryChildFragment.pendingProps = primaryChildProps; if (enableProfilerTimer && workInProgress.mode & ProfileMode) { - // Reset the durations from the first pass so they aren't included in the - // final amounts. This seems counterintuitive, since we're intentionally - // not measuring part of the render phase, but this makes it match what we - // do in Concurrent Mode. + // Reset the durations from the first pass so they aren't included in the final amounts. + // This seems counterintuitive, since we're intentionally not measuring part of the render phase, + // but this makes it match what we do in Concurrent Mode. primaryChildFragment.actualDuration = 0; primaryChildFragment.actualStartTime = -1; primaryChildFragment.selfBaseDuration = 0; @@ -2111,10 +2119,9 @@ function updateSuspenseFallbackChildren( primaryChildFragment.pendingProps = primaryChildProps; if (enableProfilerTimer && workInProgress.mode & ProfileMode) { - // Reset the durations from the first pass so they aren't included in the - // final amounts. This seems counterintuitive, since we're intentionally - // not measuring part of the render phase, but this makes it match what we - // do in Concurrent Mode. + // Reset the durations from the first pass so they aren't included in the final amounts. + // This seems counterintuitive, since we're intentionally not measuring part of the render phase, + // but this makes it match what we do in Concurrent Mode. primaryChildFragment.actualDuration = 0; primaryChildFragment.actualStartTime = -1; primaryChildFragment.selfBaseDuration = @@ -2970,6 +2977,13 @@ function bailoutOnAlreadyFinishedWork( // Check if the children have any pending work. if (!includesSomeLane(renderLanes, workInProgress.childLanes)) { + if (enableProfilerTimer) { + if (current !== null) { + workInProgress.treeBaseDuration = current.treeBaseDuration; + workInProgress.selfBaseDuration = 0; + } + } + // 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. diff --git a/packages/react-reconciler/src/ReactFiberCompleteWork.new.js b/packages/react-reconciler/src/ReactFiberCompleteWork.new.js index 3cb08b48eea5e..d5a479357b255 100644 --- a/packages/react-reconciler/src/ReactFiberCompleteWork.new.js +++ b/packages/react-reconciler/src/ReactFiberCompleteWork.new.js @@ -8,7 +8,7 @@ */ import type {Fiber} from './ReactInternalTypes'; -import type {Lanes} from './ReactFiberLane'; +import type {Lanes, Lane} from './ReactFiberLane'; import type { ReactFundamentalComponentInstance, ReactScopeInstance, @@ -58,7 +58,12 @@ import { OffscreenComponent, LegacyHiddenComponent, } from './ReactWorkTags'; -import {NoMode, BlockingMode, ProfileMode} from './ReactTypeOfMode'; +import { + NoMode, + BlockingMode, + ConcurrentMode, + ProfileMode, +} from './ReactTypeOfMode'; import { Ref, Update, @@ -66,6 +71,8 @@ import { DidCapture, Snapshot, MutationMask, + PerformedWork, + StaticMask, } from './ReactFiberFlags'; import invariant from 'shared/invariant'; @@ -137,12 +144,22 @@ import { renderHasNotSuspendedYet, popRenderLanes, getRenderTargetTime, + subtreeRenderLanes, } from './ReactFiberWorkLoop.new'; import {createFundamentalStateInstance} from './ReactFiberFundamental.new'; -import {OffscreenLane, SomeRetryLane} from './ReactFiberLane'; +import { + OffscreenLane, + SomeRetryLane, + NoLanes, + includesSomeLane, + mergeLanes, +} from './ReactFiberLane'; import {resetChildFibers} from './ReactChildFiber.new'; import {createScopeInstance} from './ReactFiberScope.new'; -import {transferActualDuration} from './ReactProfilerTimer.new'; +import { + stopProfilerTimerIfRunning, + stopProfilerTimerIfRunningAndRecordDelta, +} from './ReactProfilerTimer.new'; function markUpdate(workInProgress: Fiber) { // Tag the fiber with an update effect. This turns a Placement into @@ -668,6 +685,101 @@ function cutOffTailIfNeeded( } } +export function bubbleProfilerDurationsAfterError(erroredWork: Fiber): void { + if (enableProfilerTimer) { + if ((erroredWork.mode & ProfileMode) !== NoMode) { + const parent = erroredWork.return; + if (parent !== null) { + // TODO (effects) Document + parent.actualDuration += erroredWork.actualDuration; + + // TODO (effects) Document + parent.treeBaseDuration = 0; + } + } + } +} + +// TODO (effects) Temorary method; replace with bubblePropertiesToParent +function bubbleProperties(completedWork: Fiber): void { + bubblePropertiesFromChildren(completedWork); + bubblePropertiesToParent(completedWork); +} + +function bubblePropertiesToParent(completedWork: Fiber): void { + const parent = completedWork.return; + if (parent !== null) { + const didBailout = (completeWork.flags & PerformedWork) !== NoFlags; + if (!didBailout) { + if (enableProfilerTimer) { + if ((completedWork.mode & ProfileMode) !== NoMode) { + stopProfilerTimerIfRunningAndRecordDelta(completedWork, true); + + // At this point child base durations have already bubbled up to treeBaseDuration. + // Add our own base duration before bubbling further to the parent Fiber. + completedWork.treeBaseDuration += completedWork.selfBaseDuration; + + // Bubble base durations to the parent. + parent.actualDuration += completedWork.actualDuration; + parent.treeBaseDuration += completedWork.treeBaseDuration; + } + } + } else { + if (enableProfilerTimer) { + if ((completedWork.mode & ProfileMode) !== NoMode) { + stopProfilerTimerIfRunning(completedWork); + + parent.treeBaseDuration += completedWork.treeBaseDuration; + } + } + } + } +} + +// TODO (effects) Move everything in this method into bubblePropertiesToParent +function bubblePropertiesFromChildren(completedWork: Fiber): void { + let newChildLanes = NoLanes; + let subtreeFlags = NoFlags; + + const didBailout = + completedWork.alternate !== null && + completedWork.alternate.child === completedWork.child; + if (!didBailout) { + let child = completedWork.child; + while (child !== null) { + newChildLanes = mergeLanes( + newChildLanes, + mergeLanes(child.lanes, child.childLanes), + ); + + subtreeFlags |= child.subtreeFlags; + subtreeFlags |= child.flags; + + child = child.sibling; + } + } else { + let child = completedWork.child; + while (child !== null) { + newChildLanes = mergeLanes( + newChildLanes, + mergeLanes(child.lanes, child.childLanes), + ); + + // "Static" flags share the lifetime of the fiber/hook they belong to, + // so we should bubble those up even during a bailout. All the other + // flags have a lifetime only of a single render + commit, so we should + // ignore them. + subtreeFlags |= child.subtreeFlags & StaticMask; + subtreeFlags |= child.flags & StaticMask; + + child = child.sibling; + } + } + + completedWork.childLanes = newChildLanes; + completedWork.subtreeFlags |= subtreeFlags; +} + function completeWork( current: Fiber | null, workInProgress: Fiber, @@ -686,12 +798,14 @@ function completeWork( case Profiler: case ContextConsumer: case MemoComponent: + bubbleProperties(workInProgress); return null; case ClassComponent: { const Component = workInProgress.type; if (isLegacyContextProvider(Component)) { popLegacyContext(workInProgress); } + bubbleProperties(workInProgress); return null; } case HostRoot: { @@ -720,6 +834,7 @@ function completeWork( } } updateHostContainer(current, workInProgress); + bubbleProperties(workInProgress); return null; } case HostComponent: { @@ -746,6 +861,7 @@ function completeWork( 'caused by a bug in React. Please file an issue.', ); // This can happen when we abort work. + bubbleProperties(workInProgress); return null; } @@ -803,6 +919,7 @@ function completeWork( markRef(workInProgress); } } + bubbleProperties(workInProgress); return null; } case HostText: { @@ -837,6 +954,7 @@ function completeWork( ); } } + bubbleProperties(workInProgress); return null; } case SuspenseComponent: { @@ -856,6 +974,20 @@ function completeWork( if (enableSchedulerTracing) { markSpawnedWork(OffscreenLane); } + bubbleProperties(workInProgress); + if (enableProfilerTimer) { + if ((workInProgress.mode & ProfileMode) !== NoMode) { + const isTimedOutSuspense = nextState !== null; + if (isTimedOutSuspense) { + // Don't count time spent in a timed out Suspense subtree as part of the base duration. + const primaryChildFragment = workInProgress.child; + if (primaryChildFragment !== null) { + // $FlowFixMe Flow doens't support type casting in combiation with the -= operator + workInProgress.treeBaseDuration -= ((primaryChildFragment.treeBaseDuration: any): number); + } + } + } + } return null; } else { // We should never have been in a hydration state if we didn't have a current. @@ -872,6 +1004,20 @@ function completeWork( // If something suspended, schedule an effect to attach retry listeners. // So we might as well always mark this. workInProgress.flags |= Update; + bubbleProperties(workInProgress); + if (enableProfilerTimer) { + if ((workInProgress.mode & ProfileMode) !== NoMode) { + const isTimedOutSuspense = nextState !== null; + if (isTimedOutSuspense) { + // Don't count time spent in a timed out Suspense subtree as part of the base duration. + const primaryChildFragment = workInProgress.child; + if (primaryChildFragment !== null) { + // $FlowFixMe Flow doens't support type casting in combiation with the -= operator + workInProgress.treeBaseDuration -= ((primaryChildFragment.treeBaseDuration: any): number); + } + } + } + } return null; } } @@ -881,12 +1027,6 @@ function completeWork( // Something suspended. Re-render with the fallback children. workInProgress.lanes = renderLanes; // Do not reset the effect list. - if ( - enableProfilerTimer && - (workInProgress.mode & ProfileMode) !== NoMode - ) { - transferActualDuration(workInProgress); - } return workInProgress; } @@ -964,6 +1104,19 @@ function completeWork( // Always notify the callback workInProgress.flags |= Update; } + bubbleProperties(workInProgress); + if (enableProfilerTimer) { + if ((workInProgress.mode & ProfileMode) !== NoMode) { + if (nextDidTimeout) { + // Don't count time spent in a timed out Suspense subtree as part of the base duration. + const primaryChildFragment = workInProgress.child; + if (primaryChildFragment !== null) { + // $FlowFixMe Flow doens't support type casting in combiation with the -= operator + workInProgress.treeBaseDuration -= ((primaryChildFragment.treeBaseDuration: any): number); + } + } + } + } return null; } case HostPortal: @@ -972,10 +1125,12 @@ function completeWork( if (current === null) { preparePortalMount(workInProgress.stateNode.containerInfo); } + bubbleProperties(workInProgress); return null; case ContextProvider: // Pop provider fiber popProvider(workInProgress); + bubbleProperties(workInProgress); return null; case IncompleteClassComponent: { // Same as class component case. I put it down here so that the tags are @@ -984,6 +1139,7 @@ function completeWork( if (isLegacyContextProvider(Component)) { popLegacyContext(workInProgress); } + bubbleProperties(workInProgress); return null; } case SuspenseListComponent: { @@ -995,6 +1151,7 @@ function completeWork( if (renderState === null) { // We're running in the default, "independent" mode. // We don't do anything in this mode. + bubbleProperties(workInProgress); return null; } @@ -1117,6 +1274,7 @@ function completeWork( !getIsHydrating() // We don't cut it if we're hydrating. ) { // We're done. + bubbleProperties(workInProgress); return null; } } else if ( @@ -1190,6 +1348,7 @@ function completeWork( // Do a pass over the next row. return next; } + bubbleProperties(workInProgress); return null; } case FundamentalComponent: { @@ -1217,6 +1376,7 @@ function completeWork( ): any): Instance); fundamentalInstance.instance = instance; if (fundamentalImpl.reconcileChildren === false) { + bubbleProperties(workInProgress); return null; } appendAllChildren(instance, workInProgress, false, false); @@ -1239,6 +1399,7 @@ function completeWork( markUpdate(workInProgress); } } + bubbleProperties(workInProgress); return null; } break; @@ -1261,24 +1422,27 @@ function completeWork( markRef(workInProgress); } } + bubbleProperties(workInProgress); return null; } break; } case Block: if (enableBlocksAPI) { + bubbleProperties(workInProgress); return null; } break; case OffscreenComponent: case LegacyHiddenComponent: { popRenderLanes(workInProgress); + const nextState: OffscreenState | null = workInProgress.memoizedState; + const nextIsHidden = nextState !== null; + if (current !== null) { - const nextState: OffscreenState | null = workInProgress.memoizedState; const prevState: OffscreenState | null = current.memoizedState; const prevIsHidden = prevState !== null; - const nextIsHidden = nextState !== null; if ( prevIsHidden !== nextIsHidden && newProps.mode !== 'unstable-defer-without-hiding' @@ -1286,6 +1450,16 @@ function completeWork( workInProgress.flags |= Update; } } + + // Don't bubble properties for hidden children. + if ( + !nextIsHidden || + includesSomeLane(subtreeRenderLanes, (OffscreenLane: Lane)) || + (workInProgress.mode & ConcurrentMode) === NoLanes + ) { + bubbleProperties(workInProgress); + } + return null; } } diff --git a/packages/react-reconciler/src/ReactFiberUnwindWork.new.js b/packages/react-reconciler/src/ReactFiberUnwindWork.new.js index 98d1f7957f310..d6125e725594e 100644 --- a/packages/react-reconciler/src/ReactFiberUnwindWork.new.js +++ b/packages/react-reconciler/src/ReactFiberUnwindWork.new.js @@ -24,11 +24,7 @@ import { LegacyHiddenComponent, } from './ReactWorkTags'; import {DidCapture, NoFlags, ShouldCapture} from './ReactFiberFlags'; -import {NoMode, ProfileMode} from './ReactTypeOfMode'; -import { - enableSuspenseServerRenderer, - enableProfilerTimer, -} from 'shared/ReactFeatureFlags'; +import {enableSuspenseServerRenderer} from 'shared/ReactFeatureFlags'; import {popHostContainer, popHostContext} from './ReactFiberHostContext.new'; import {popSuspenseContext} from './ReactFiberSuspenseContext.new'; @@ -40,7 +36,6 @@ import { } from './ReactFiberContext.new'; import {popProvider} from './ReactFiberNewContext.new'; import {popRenderLanes} from './ReactFiberWorkLoop.new'; -import {transferActualDuration} from './ReactProfilerTimer.new'; import invariant from 'shared/invariant'; @@ -54,12 +49,6 @@ function unwindWork(workInProgress: Fiber, renderLanes: Lanes) { const flags = workInProgress.flags; if (flags & ShouldCapture) { workInProgress.flags = (flags & ~ShouldCapture) | DidCapture; - if ( - enableProfilerTimer && - (workInProgress.mode & ProfileMode) !== NoMode - ) { - transferActualDuration(workInProgress); - } return workInProgress; } return null; @@ -100,12 +89,6 @@ function unwindWork(workInProgress: Fiber, renderLanes: Lanes) { if (flags & ShouldCapture) { workInProgress.flags = (flags & ~ShouldCapture) | DidCapture; // Captured a suspense effect. Re-render the boundary. - if ( - enableProfilerTimer && - (workInProgress.mode & ProfileMode) !== NoMode - ) { - transferActualDuration(workInProgress); - } return workInProgress; } return null; diff --git a/packages/react-reconciler/src/ReactFiberWorkLoop.new.js b/packages/react-reconciler/src/ReactFiberWorkLoop.new.js index 1e386c3309548..fc58c8a484216 100644 --- a/packages/react-reconciler/src/ReactFiberWorkLoop.new.js +++ b/packages/react-reconciler/src/ReactFiberWorkLoop.new.js @@ -115,8 +115,6 @@ import { MemoComponent, SimpleMemoComponent, Block, - OffscreenComponent, - LegacyHiddenComponent, ScopeComponent, } from './ReactWorkTags'; import {LegacyRoot} from './ReactRootTags'; @@ -139,7 +137,6 @@ import { MutationMask, LayoutMask, PassiveMask, - StaticMask, } from './ReactFiberFlags'; import { NoLanePriority, @@ -151,7 +148,6 @@ import { NoLane, SyncLane, SyncBatchedLane, - OffscreenLane, NoTimestamp, findUpdateLane, findTransitionLane, @@ -183,7 +179,10 @@ import { } from './ReactFiberLane'; import {requestCurrentTransition, NoTransition} from './ReactFiberTransition'; import {beginWork as originalBeginWork} from './ReactFiberBeginWork.new'; -import {completeWork} from './ReactFiberCompleteWork.new'; +import { + bubbleProfilerDurationsAfterError, + completeWork, +} from './ReactFiberCompleteWork.new'; import {unwindWork, unwindInterruptedWork} from './ReactFiberUnwindWork.new'; import { throwException, @@ -290,7 +289,7 @@ let workInProgressRootRenderLanes: Lanes = NoLanes; // // Most things in the work loop should deal with workInProgressRootRenderLanes. // Most things in begin/complete phases should deal with subtreeRenderLanes. -let subtreeRenderLanes: Lanes = NoLanes; +export let subtreeRenderLanes: Lanes = NoLanes; const subtreeRenderLanesCursor: StackCursor = createCursor(NoLanes); // Whether to root completed, errored, suspended, etc. @@ -1386,9 +1385,16 @@ function handleError(root, thrownValue): void { if (enableProfilerTimer && erroredWork.mode & ProfileMode) { // Record the time spent rendering before an error was thrown. This - // avoids inaccurate Profiler durations in the case of a - // suspended render. + // avoids inaccurate Profiler durations in the case of a suspended render. stopProfilerTimerIfRunningAndRecordDelta(erroredWork, true); + + const isSuspense = + thrownValue !== null && + typeof thrownValue === 'object' && + typeof thrownValue.then === 'function'; + if (!isSuspense) { + bubbleProfilerDurationsAfterError(erroredWork); + } } throwException( @@ -1700,18 +1706,7 @@ function completeUnitOfWork(unitOfWork: Fiber): void { // Check if the work completed or if something threw. if ((completedWork.flags & Incomplete) === NoFlags) { setCurrentDebugFiberInDEV(completedWork); - let next; - if ( - !enableProfilerTimer || - (completedWork.mode & ProfileMode) === NoMode - ) { - next = completeWork(current, completedWork, subtreeRenderLanes); - } else { - startProfilerTimer(completedWork); - next = completeWork(current, completedWork, subtreeRenderLanes); - // Update render duration assuming we didn't error. - stopProfilerTimerIfRunningAndRecordDelta(completedWork, false); - } + const next = completeWork(current, completedWork, subtreeRenderLanes); resetCurrentDebugFiberInDEV(); if (next !== null) { @@ -1719,8 +1714,6 @@ function completeUnitOfWork(unitOfWork: Fiber): void { workInProgress = next; return; } - - resetChildLanes(completedWork); } else { // This fiber did not complete because something threw. Pop values off // the stack without entering the complete phase. If this is a boundary, @@ -1745,15 +1738,6 @@ function completeUnitOfWork(unitOfWork: Fiber): void { ) { // Record the render duration for the fiber that errored. stopProfilerTimerIfRunningAndRecordDelta(completedWork, false); - - // Include the time spent working on failed children before continuing. - let actualDuration = completedWork.actualDuration; - let child = completedWork.child; - while (child !== null) { - actualDuration += child.actualDuration; - child = child.sibling; - } - completedWork.actualDuration = actualDuration; } if (returnFiber !== null) { @@ -1782,150 +1766,6 @@ function completeUnitOfWork(unitOfWork: Fiber): void { } } -function resetChildLanes(completedWork: Fiber) { - if ( - // TODO: Move this check out of the hot path by moving `resetChildLanes` - // to switch statement in `completeWork`. - (completedWork.tag === LegacyHiddenComponent || - completedWork.tag === OffscreenComponent) && - completedWork.memoizedState !== null && - !includesSomeLane(subtreeRenderLanes, (OffscreenLane: Lane)) && - (completedWork.mode & ConcurrentMode) !== NoLanes - ) { - // The children of this component are hidden. Don't bubble their - // expiration times. - return; - } - - const didBailout = - completedWork.alternate !== null && - completedWork.alternate.child === completedWork.child; - - let newChildLanes = NoLanes; - let subtreeFlags = NoFlags; - - if (!didBailout) { - // Bubble up the earliest expiration time. - if (enableProfilerTimer && (completedWork.mode & ProfileMode) !== NoMode) { - // In profiling mode, resetChildExpirationTime is also used to reset - // profiler durations. - let actualDuration = completedWork.actualDuration; - let treeBaseDuration = ((completedWork.selfBaseDuration: any): number); - - let child = completedWork.child; - while (child !== null) { - newChildLanes = mergeLanes( - newChildLanes, - mergeLanes(child.lanes, child.childLanes), - ); - - subtreeFlags |= child.subtreeFlags; - subtreeFlags |= child.flags; - - // When a fiber is cloned, its actualDuration is reset to 0. This value will - // only be updated if work is done on the fiber (i.e. it doesn't bailout). - // When work is done, it should bubble to the parent's actualDuration. If - // the fiber has not been cloned though, (meaning no work was done), then - // this value will reflect the amount of time spent working on a previous - // render. In that case it should not bubble. We determine whether it was - // cloned by comparing the child pointer. - actualDuration += child.actualDuration; - - treeBaseDuration += child.treeBaseDuration; - child = child.sibling; - } - - const isTimedOutSuspense = - completedWork.tag === SuspenseComponent && - completedWork.memoizedState !== null; - if (isTimedOutSuspense) { - // Don't count time spent in a timed out Suspense subtree as part of the base duration. - const primaryChildFragment = completedWork.child; - if (primaryChildFragment !== null) { - treeBaseDuration -= ((primaryChildFragment.treeBaseDuration: any): number); - } - } - - completedWork.actualDuration = actualDuration; - completedWork.treeBaseDuration = treeBaseDuration; - } else { - let child = completedWork.child; - while (child !== null) { - newChildLanes = mergeLanes( - newChildLanes, - mergeLanes(child.lanes, child.childLanes), - ); - - subtreeFlags |= child.subtreeFlags; - subtreeFlags |= child.flags; - - child = child.sibling; - } - } - - completedWork.subtreeFlags |= subtreeFlags; - } else { - // Bubble up the earliest expiration time. - if (enableProfilerTimer && (completedWork.mode & ProfileMode) !== NoMode) { - // In profiling mode, resetChildExpirationTime is also used to reset - // profiler durations. - let treeBaseDuration = ((completedWork.selfBaseDuration: any): number); - - let child = completedWork.child; - while (child !== null) { - newChildLanes = mergeLanes( - newChildLanes, - mergeLanes(child.lanes, child.childLanes), - ); - - // "Static" flags share the lifetime of the fiber/hook they belong to, - // so we should bubble those up even during a bailout. All the other - // flags have a lifetime only of a single render + commit, so we should - // ignore them. - subtreeFlags |= child.subtreeFlags & StaticMask; - subtreeFlags |= child.flags & StaticMask; - - treeBaseDuration += child.treeBaseDuration; - child = child.sibling; - } - - const isTimedOutSuspense = - completedWork.tag === SuspenseComponent && - completedWork.memoizedState !== null; - if (isTimedOutSuspense) { - // Don't count time spent in a timed out Suspense subtree as part of the base duration. - const primaryChildFragment = completedWork.child; - if (primaryChildFragment !== null) { - treeBaseDuration -= ((primaryChildFragment.treeBaseDuration: any): number); - } - } - - completedWork.treeBaseDuration = treeBaseDuration; - } else { - let child = completedWork.child; - while (child !== null) { - newChildLanes = mergeLanes( - newChildLanes, - mergeLanes(child.lanes, child.childLanes), - ); - - // "Static" flags share the lifetime of the fiber/hook they belong to, - // so we should bubble those up even during a bailout. All the other - // flags have a lifetime only of a single render + commit, so we should - // ignore them. - subtreeFlags |= child.subtreeFlags & StaticMask; - subtreeFlags |= child.flags & StaticMask; - - child = child.sibling; - } - } - - completedWork.subtreeFlags |= subtreeFlags; - } - - completedWork.childLanes = newChildLanes; -} - function commitRoot(root) { const renderPriorityLevel = getCurrentPriorityLevel(); runWithPriority( diff --git a/packages/react-reconciler/src/ReactProfilerTimer.new.js b/packages/react-reconciler/src/ReactProfilerTimer.new.js index e7f58e1b1bc2d..69183f70e6453 100644 --- a/packages/react-reconciler/src/ReactProfilerTimer.new.js +++ b/packages/react-reconciler/src/ReactProfilerTimer.new.js @@ -148,17 +148,6 @@ function startPassiveEffectTimer(): void { passiveEffectStartTime = now(); } -function transferActualDuration(fiber: Fiber): void { - // Transfer time spent rendering these children so we don't lose it - // after we rerender. This is used as a helper in special cases - // where we should count the work of multiple passes. - let child = fiber.child; - while (child) { - fiber.actualDuration += child.actualDuration; - child = child.sibling; - } -} - export { getCommitTime, recordCommitTime, @@ -169,5 +158,4 @@ export { startProfilerTimer, stopProfilerTimerIfRunning, stopProfilerTimerIfRunningAndRecordDelta, - transferActualDuration, };