@@ -72,6 +72,7 @@ import {readTemporaryReference} from './ReactFlightTemporaryReferences';
7272import {
7373 markAllTracksInOrder,
7474 logComponentRender,
75+ logDedupedComponentRender,
7576} from './ReactFlightPerformanceTrack';
7677
7778import {
@@ -130,6 +131,7 @@ export type JSONValue =
130131type ProfilingResult = {
131132 track: number,
132133 endTime: number,
134+ component: null | ReactComponentInfo,
133135};
134136
135137const ROW_ID = 0;
@@ -647,7 +649,7 @@ export function reportGlobalError(response: Response, error: Error): void {
647649 });
648650 if (enableProfilerTimer && enableComponentPerformanceTrack) {
649651 markAllTracksInOrder();
650- flushComponentPerformance(getChunk(response, 0), 0, -Infinity);
652+ flushComponentPerformance(getChunk(response, 0), 0, -Infinity, -Infinity );
651653 }
652654}
653655
@@ -2748,7 +2750,8 @@ function resolveTypedArray(
27482750function flushComponentPerformance(
27492751 root: SomeChunk<any>,
27502752 trackIdx: number, // Next available track
2751- trackTime: number, // The time after which it is available
2753+ trackTime: number, // The time after which it is available,
2754+ parentEndTime: number,
27522755): ProfilingResult {
27532756 if (!enableProfilerTimer || !enableComponentPerformanceTrack) {
27542757 // eslint-disable-next-line react-internal/prod-error-codes
@@ -2765,6 +2768,22 @@ function flushComponentPerformance(
27652768 // chunk in two places. We should extend the current end time as if it was
27662769 // rendered as part of this tree.
27672770 const previousResult: ProfilingResult = root._children;
2771+ const previousEndTime = previousResult.endTime;
2772+ if (
2773+ parentEndTime > -Infinity &&
2774+ parentEndTime < previousEndTime &&
2775+ previousResult.component !== null
2776+ ) {
2777+ // Log a placeholder for the deduped value under this child starting
2778+ // from the end of the self time of the parent and spanning until the
2779+ // the deduped end.
2780+ logDedupedComponentRender(
2781+ previousResult.component,
2782+ trackIdx,
2783+ parentEndTime,
2784+ previousEndTime,
2785+ );
2786+ }
27682787 // Since we didn't bump the track this time, we just return the same track.
27692788 previousResult.track = trackIdx;
27702789 return previousResult;
@@ -2792,15 +2811,27 @@ function flushComponentPerformance(
27922811 // The start time of this component is before the end time of the previous
27932812 // component on this track so we need to bump the next one to a parallel track.
27942813 trackIdx++;
2795- trackTime = startTime;
27962814 }
2815+ trackTime = startTime;
27972816 break;
27982817 }
27992818 }
28002819 }
2820+ for (let i = debugInfo.length - 1; i >= 0; i--) {
2821+ const info = debugInfo[i];
2822+ if (typeof info.time === 'number') {
2823+ if (info.time > parentEndTime) {
2824+ parentEndTime = info.time;
2825+ }
2826+ }
2827+ }
28012828 }
28022829
2803- const result: ProfilingResult = {track: trackIdx, endTime: -Infinity};
2830+ const result: ProfilingResult = {
2831+ track: trackIdx,
2832+ endTime: -Infinity,
2833+ component: null,
2834+ };
28042835 root._children = result;
28052836 let childrenEndTime = -Infinity;
28062837 let childTrackIdx = trackIdx;
@@ -2810,7 +2841,11 @@ function flushComponentPerformance(
28102841 children[i],
28112842 childTrackIdx,
28122843 childTrackTime,
2844+ parentEndTime,
28132845 );
2846+ if (childResult.component !== null) {
2847+ result.component = childResult.component;
2848+ }
28142849 childTrackIdx = childResult.track;
28152850 const childEndTime = childResult.endTime;
28162851 childTrackTime = childEndTime;
@@ -2842,6 +2877,8 @@ function flushComponentPerformance(
28422877 endTime,
28432878 childrenEndTime,
28442879 );
2880+ // Track the root most component of the result for deduping logging.
2881+ result.component = componentInfo;
28452882 }
28462883 }
28472884 }
0 commit comments