@@ -2902,6 +2902,46 @@ function resolveTypedArray(
2902
2902
resolveBuffer ( response , id , view ) ;
2903
2903
}
2904
2904
2905
+ function logComponentInfo(
2906
+ response: Response,
2907
+ root: SomeChunk< any > ,
2908
+ componentInfo: ReactComponentInfo,
2909
+ trackIdx: number,
2910
+ startTime: number,
2911
+ componentEndTime: number,
2912
+ childrenEndTime: number,
2913
+ isLastComponent: boolean,
2914
+ ): void {
2915
+ // $FlowFixMe: Refined.
2916
+ if (
2917
+ isLastComponent &&
2918
+ root . status === ERRORED &&
2919
+ root . reason !== response . _closedReason
2920
+ ) {
2921
+ // If this is the last component to render before this chunk rejected, then conceptually
2922
+ // this component errored. If this was a cancellation then it wasn't this component that
2923
+ // errored.
2924
+ logComponentErrored (
2925
+ componentInfo ,
2926
+ trackIdx ,
2927
+ startTime ,
2928
+ componentEndTime ,
2929
+ childrenEndTime ,
2930
+ response . _rootEnvironmentName ,
2931
+ root . reason ,
2932
+ ) ;
2933
+ } else {
2934
+ logComponentRender (
2935
+ componentInfo ,
2936
+ trackIdx ,
2937
+ startTime ,
2938
+ componentEndTime ,
2939
+ childrenEndTime ,
2940
+ response . _rootEnvironmentName ,
2941
+ ) ;
2942
+ }
2943
+ }
2944
+
2905
2945
function flushComponentPerformance (
2906
2946
response : Response ,
2907
2947
root : SomeChunk < any > ,
@@ -2979,6 +3019,7 @@ function flushComponentPerformance(
2979
3019
if ( typeof info . time === 'number' ) {
2980
3020
if ( info . time > parentEndTime ) {
2981
3021
parentEndTime = info . time ;
3022
+ break ; // We assume the highest number is at the end.
2982
3023
}
2983
3024
}
2984
3025
}
@@ -3013,77 +3054,57 @@ function flushComponentPerformance(
3013
3054
}
3014
3055
3015
3056
if ( debugInfo ) {
3057
+ // Write debug info in reverse order (just like stack traces).
3016
3058
let endTime = 0 ;
3059
+ let componentEndTime = 0 ;
3017
3060
let isLastComponent = true ;
3061
+ let candidateInfo = null ; // An entry we can write once we know its start time.
3018
3062
for ( let i = debugInfo . length - 1 ; i >= 0 ; i -- ) {
3019
3063
const info = debugInfo [ i ] ;
3020
3064
if ( typeof info . time === 'number' ) {
3021
- if ( info . time > childrenEndTime ) {
3022
- childrenEndTime = info . time ;
3065
+ const time = info . time ;
3066
+ if ( time > childrenEndTime ) {
3067
+ childrenEndTime = time ;
3023
3068
}
3024
- if ( endTime === 0 ) {
3069
+ if ( componentEndTime === 0 ) {
3025
3070
// Last timestamp is the end of the last component.
3026
- endTime = info . time ;
3071
+ componentEndTime = info . time ;
3027
3072
}
3028
- }
3029
- if ( typeof info . name === 'string' && i > 0 ) {
3030
- // $FlowFixMe: Refined.
3031
- const componentInfo : ReactComponentInfo = info ;
3032
- const startTimeInfo = debugInfo [ i - 1 ] ;
3033
- if ( typeof startTimeInfo . time === 'number' ) {
3034
- const startTime = startTimeInfo . time ;
3035
- if (
3036
- isLastComponent &&
3037
- root . status === ERRORED &&
3038
- root . reason !== response . _closedReason
3039
- ) {
3040
- // If this is the last component to render before this chunk rejected, then conceptually
3041
- // this component errored. If this was a cancellation then it wasn't this component that
3042
- // errored.
3043
- logComponentErrored (
3073
+ if ( candidateInfo !== null ) {
3074
+ if ( typeof candidateInfo . name === 'string' ) {
3075
+ // $FlowFixMe: Refined.
3076
+ const componentInfo : ReactComponentInfo = candidateInfo ;
3077
+ logComponentInfo (
3078
+ response ,
3079
+ root ,
3044
3080
componentInfo ,
3045
3081
trackIdx ,
3046
- startTime ,
3047
- endTime ,
3082
+ time ,
3083
+ componentEndTime ,
3048
3084
childrenEndTime ,
3049
- response . _rootEnvironmentName ,
3050
- root . reason ,
3085
+ isLastComponent ,
3051
3086
) ;
3052
- } else {
3053
- logComponentRender (
3054
- componentInfo ,
3087
+ componentEndTime = time ; // The end time of previous component is the start time of the next.
3088
+ // Track the root most component of the result for deduping logging.
3089
+ result . component = componentInfo ;
3090
+ isLastComponent = false ;
3091
+ } else if ( candidateInfo . awaited ) {
3092
+ // $FlowFixMe: Refined.
3093
+ const asyncInfo : ReactAsyncInfo = candidateInfo ;
3094
+ logComponentAwait (
3095
+ asyncInfo ,
3055
3096
trackIdx,
3056
- startTime ,
3097
+ time ,
3057
3098
endTime,
3058
- childrenEndTime ,
3059
3099
response . _rootEnvironmentName,
3060
3100
) ;
3061
3101
}
3062
- // Track the root most component of the result for deduping logging.
3063
- result . component = componentInfo ;
3064
- // Set the end time of the previous component to the start of the previous.
3065
- endTime = startTime ;
3066
- }
3067
- isLastComponent = false ;
3068
- } else if ( info . awaited && i > 0 && i < debugInfo . length - 2 ) {
3069
- // $FlowFixMe: Refined.
3070
- const asyncInfo : ReactAsyncInfo = info ;
3071
- const startTimeInfo = debugInfo [ i - 1 ] ;
3072
- const endTimeInfo = debugInfo [ i + 1 ] ;
3073
- if (
3074
- typeof startTimeInfo . time === 'number' &&
3075
- typeof endTimeInfo . time === 'number'
3076
- ) {
3077
- const awaitStartTime = startTimeInfo . time ;
3078
- const awaitEndTime = endTimeInfo . time ;
3079
- logComponentAwait (
3080
- asyncInfo ,
3081
- trackIdx ,
3082
- awaitStartTime ,
3083
- awaitEndTime ,
3084
- response . _rootEnvironmentName ,
3085
- ) ;
3102
+ candidateInfo = null ;
3086
3103
}
3104
+ endTime = time ; // The end time of the next entry is this time.
3105
+ } else {
3106
+ // Otherwise, store it until we know its start time.
3107
+ candidateInfo = info ;
3087
3108
}
3088
3109
}
3089
3110
}
0 commit comments