@@ -74,6 +74,7 @@ import {readTemporaryReference} from './ReactFlightTemporaryReferences';
74
74
import {
75
75
markAllTracksInOrder,
76
76
logComponentRender,
77
+ logDedupedComponentRender,
77
78
} from './ReactFlightPerformanceTrack';
78
79
79
80
import {
@@ -132,6 +133,7 @@ export type JSONValue =
132
133
type ProfilingResult = {
133
134
track: number,
134
135
endTime: number,
136
+ component: null | ReactComponentInfo,
135
137
};
136
138
137
139
const ROW_ID = 0;
@@ -653,7 +655,7 @@ export function reportGlobalError(response: Response, error: Error): void {
653
655
});
654
656
if (enableProfilerTimer && enableComponentPerformanceTrack) {
655
657
markAllTracksInOrder();
656
- flushComponentPerformance(getChunk(response, 0), 0, -Infinity);
658
+ flushComponentPerformance(getChunk(response, 0), 0, -Infinity, -Infinity );
657
659
}
658
660
}
659
661
@@ -2761,7 +2763,8 @@ function resolveTypedArray(
2761
2763
function flushComponentPerformance(
2762
2764
root: SomeChunk<any>,
2763
2765
trackIdx: number, // Next available track
2764
- trackTime: number, // The time after which it is available
2766
+ trackTime: number, // The time after which it is available,
2767
+ parentEndTime: number,
2765
2768
): ProfilingResult {
2766
2769
if (!enableProfilerTimer || !enableComponentPerformanceTrack) {
2767
2770
// eslint-disable-next-line react-internal/prod-error-codes
@@ -2778,6 +2781,22 @@ function flushComponentPerformance(
2778
2781
// chunk in two places. We should extend the current end time as if it was
2779
2782
// rendered as part of this tree.
2780
2783
const previousResult: ProfilingResult = root._children;
2784
+ const previousEndTime = previousResult.endTime;
2785
+ if (
2786
+ parentEndTime > -Infinity &&
2787
+ parentEndTime < previousEndTime &&
2788
+ previousResult.component !== null
2789
+ ) {
2790
+ // Log a placeholder for the deduped value under this child starting
2791
+ // from the end of the self time of the parent and spanning until the
2792
+ // the deduped end.
2793
+ logDedupedComponentRender(
2794
+ previousResult.component,
2795
+ trackIdx,
2796
+ parentEndTime,
2797
+ previousEndTime,
2798
+ );
2799
+ }
2781
2800
// Since we didn't bump the track this time, we just return the same track.
2782
2801
previousResult.track = trackIdx;
2783
2802
return previousResult;
@@ -2805,15 +2824,27 @@ function flushComponentPerformance(
2805
2824
// The start time of this component is before the end time of the previous
2806
2825
// component on this track so we need to bump the next one to a parallel track.
2807
2826
trackIdx++;
2808
- trackTime = startTime;
2809
2827
}
2828
+ trackTime = startTime;
2810
2829
break;
2811
2830
}
2812
2831
}
2813
2832
}
2833
+ for (let i = debugInfo.length - 1; i >= 0; i--) {
2834
+ const info = debugInfo[i];
2835
+ if (typeof info.time === 'number') {
2836
+ if (info.time > parentEndTime) {
2837
+ parentEndTime = info.time;
2838
+ }
2839
+ }
2840
+ }
2814
2841
}
2815
2842
2816
- const result: ProfilingResult = {track: trackIdx, endTime: -Infinity};
2843
+ const result: ProfilingResult = {
2844
+ track: trackIdx,
2845
+ endTime: -Infinity,
2846
+ component: null,
2847
+ };
2817
2848
root._children = result;
2818
2849
let childrenEndTime = -Infinity;
2819
2850
let childTrackIdx = trackIdx;
@@ -2823,7 +2854,11 @@ function flushComponentPerformance(
2823
2854
children[i],
2824
2855
childTrackIdx,
2825
2856
childTrackTime,
2857
+ parentEndTime,
2826
2858
);
2859
+ if (childResult.component !== null) {
2860
+ result.component = childResult.component;
2861
+ }
2827
2862
childTrackIdx = childResult.track;
2828
2863
const childEndTime = childResult.endTime;
2829
2864
childTrackTime = childEndTime;
@@ -2855,6 +2890,8 @@ function flushComponentPerformance(
2855
2890
endTime,
2856
2891
childrenEndTime,
2857
2892
);
2893
+ // Track the root most component of the result for deduping logging.
2894
+ result.component = componentInfo;
2858
2895
}
2859
2896
}
2860
2897
}
0 commit comments