Skip to content

Commit

Permalink
Mark all lanes in order on every new render
Browse files Browse the repository at this point in the history
  • Loading branch information
sebmarkbage committed Nov 22, 2024
1 parent e697386 commit f68d9c9
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 3 deletions.
59 changes: 57 additions & 2 deletions packages/react-reconciler/src/ReactFiberPerformanceTrack.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ const COMPONENTS_TRACK = 'Components ⚛';

// Reused to avoid thrashing the GC.
const reusableComponentDevToolDetails = {
dataType: 'track-entry',
color: 'primary',
track: COMPONENTS_TRACK,
};
Expand All @@ -40,7 +39,6 @@ const reusableComponentOptions = {
const LANES_TRACK_GROUP = 'Scheduler ⚛';

const reusableLaneDevToolDetails = {
dataType: 'track-entry',
color: 'primary',
track: 'Blocking', // Lane
trackGroup: LANES_TRACK_GROUP,
Expand All @@ -57,6 +55,63 @@ export function setCurrentTrackFromLanes(lanes: number): void {
reusableLaneDevToolDetails.track = getGroupNameOfHighestPriorityLane(lanes);
}

const blockingLaneMarker = {
startTime: 0,
detail: {
devtools: {
color: 'primary-light',
track: 'Blocking',
trackGroup: LANES_TRACK_GROUP,
},
},
};

const transitionLaneMarker = {
startTime: 0,
detail: {
devtools: {
color: 'primary-light',
track: 'Transition',
trackGroup: LANES_TRACK_GROUP,
},
},
};

const suspenseLaneMarker = {
startTime: 0,
detail: {
devtools: {
color: 'primary-light',
track: 'Suspense',
trackGroup: LANES_TRACK_GROUP,
},
},
};

const idleLaneMarker = {
startTime: 0,
detail: {
devtools: {
color: 'primary-light',
track: 'Idle',
trackGroup: LANES_TRACK_GROUP,
},
},
};

export function markAllLanesInOrder() {
if (supportsUserTiming) {
// Ensure we create all tracks in priority order. Currently performance.mark() are in
// first insertion order but performance.measure() are in the reverse order. We can
// always add the 0 time slot even if it's in the past. That's still considered for
// ordering.
performance.mark('Blocking Track', blockingLaneMarker);
performance.mark('Transition Track', transitionLaneMarker);
performance.mark('Suspense Track', suspenseLaneMarker);
performance.mark('Idle Track', idleLaneMarker);
}
}

export function logComponentRender(
fiber: Fiber,
startTime: number,
Expand Down
12 changes: 11 additions & 1 deletion packages/react-reconciler/src/ReactFiberWorkLoop.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ import {
logYieldTime,
logActionYieldTime,
logSuspendedYieldTime,
setCurrentTrackFromLanes,
markAllLanesInOrder,
} from './ReactFiberPerformanceTrack';

import {
Expand Down Expand Up @@ -271,7 +273,6 @@ import {
yieldReason,
startPingTimerByLanes,
} from './ReactProfilerTimer';
import {setCurrentTrackFromLanes} from './ReactFiberPerformanceTrack';

// DEV stuff
import getComponentNameFromFiber from 'react-reconciler/src/getComponentNameFromFiber';
Expand Down Expand Up @@ -1727,6 +1728,15 @@ function finalizeRender(lanes: Lanes, finalizationTime: number): void {

function prepareFreshStack(root: FiberRoot, lanes: Lanes): Fiber {
if (enableProfilerTimer && enableComponentPerformanceTrack) {
// The order of tracks within a group are determined by the earliest start time.
// Are tracks should show up in priority order and we should ideally always show
// every track. This is a hack to ensure that we're displaying all tracks in the
// right order. Ideally we could do this only once but because calls that aren't
// recorded aren't considered for ordering purposes, we need to keep adding these
// over and over again in case recording has just started. We can't tell when
// recording starts.
markAllLanesInOrder();

const previousRenderStartTime = renderStartTime;
// Starting a new render. Log the end of any previous renders and the
// blocked time before the render started.
Expand Down

0 comments on commit f68d9c9

Please sign in to comment.