@@ -72,6 +72,7 @@ import {readTemporaryReference} from './ReactFlightTemporaryReferences';
72
72
import {
73
73
markAllTracksInOrder,
74
74
logComponentRender,
75
+ logDedupedComponentRender,
75
76
} from './ReactFlightPerformanceTrack';
76
77
77
78
import {
@@ -130,6 +131,7 @@ export type JSONValue =
130
131
type ProfilingResult = {
131
132
track: number,
132
133
endTime: number,
134
+ component: null | ReactComponentInfo,
133
135
};
134
136
135
137
const ROW_ID = 0;
@@ -647,7 +649,7 @@ export function reportGlobalError(response: Response, error: Error): void {
647
649
});
648
650
if (enableProfilerTimer && enableComponentPerformanceTrack) {
649
651
markAllTracksInOrder();
650
- flushComponentPerformance(getChunk(response, 0), 0, -Infinity);
652
+ flushComponentPerformance(getChunk(response, 0), 0, -Infinity, -Infinity );
651
653
}
652
654
}
653
655
@@ -2748,7 +2750,8 @@ function resolveTypedArray(
2748
2750
function flushComponentPerformance(
2749
2751
root: SomeChunk<any>,
2750
2752
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,
2752
2755
): ProfilingResult {
2753
2756
if (!enableProfilerTimer || !enableComponentPerformanceTrack) {
2754
2757
// eslint-disable-next-line react-internal/prod-error-codes
@@ -2765,6 +2768,22 @@ function flushComponentPerformance(
2765
2768
// chunk in two places. We should extend the current end time as if it was
2766
2769
// rendered as part of this tree.
2767
2770
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
+ }
2768
2787
// Since we didn't bump the track this time, we just return the same track.
2769
2788
previousResult.track = trackIdx;
2770
2789
return previousResult;
@@ -2792,15 +2811,27 @@ function flushComponentPerformance(
2792
2811
// The start time of this component is before the end time of the previous
2793
2812
// component on this track so we need to bump the next one to a parallel track.
2794
2813
trackIdx++;
2795
- trackTime = startTime;
2796
2814
}
2815
+ trackTime = startTime;
2797
2816
break;
2798
2817
}
2799
2818
}
2800
2819
}
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
+ }
2801
2828
}
2802
2829
2803
- const result: ProfilingResult = {track: trackIdx, endTime: -Infinity};
2830
+ const result: ProfilingResult = {
2831
+ track: trackIdx,
2832
+ endTime: -Infinity,
2833
+ component: null,
2834
+ };
2804
2835
root._children = result;
2805
2836
let childrenEndTime = -Infinity;
2806
2837
let childTrackIdx = trackIdx;
@@ -2810,7 +2841,11 @@ function flushComponentPerformance(
2810
2841
children[i],
2811
2842
childTrackIdx,
2812
2843
childTrackTime,
2844
+ parentEndTime,
2813
2845
);
2846
+ if (childResult.component !== null) {
2847
+ result.component = childResult.component;
2848
+ }
2814
2849
childTrackIdx = childResult.track;
2815
2850
const childEndTime = childResult.endTime;
2816
2851
childTrackTime = childEndTime;
@@ -2842,6 +2877,8 @@ function flushComponentPerformance(
2842
2877
endTime,
2843
2878
childrenEndTime,
2844
2879
);
2880
+ // Track the root most component of the result for deduping logging.
2881
+ result.component = componentInfo;
2845
2882
}
2846
2883
}
2847
2884
}
0 commit comments