@@ -2209,6 +2209,8 @@ function recursivelyTraverseLayoutEffects(
22092209}
22102210
22112211export function disappearLayoutEffects ( finishedWork : Fiber ) {
2212+ const prevEffectStart = pushComponentEffectStart ( ) ;
2213+
22122214 switch ( finishedWork . tag ) {
22132215 case FunctionComponent :
22142216 case ForwardRef :
@@ -2266,6 +2268,25 @@ export function disappearLayoutEffects(finishedWork: Fiber) {
22662268 break ;
22672269 }
22682270 }
2271+
2272+ if (
2273+ enableProfilerTimer &&
2274+ enableProfilerCommitHooks &&
2275+ enableComponentPerformanceTrack &&
2276+ ( finishedWork . mode & ProfileMode ) !== NoMode &&
2277+ componentEffectStartTime >= 0 &&
2278+ componentEffectEndTime >= 0 &&
2279+ componentEffectDuration > 0.05
2280+ ) {
2281+ logComponentEffect (
2282+ finishedWork ,
2283+ componentEffectStartTime ,
2284+ componentEffectEndTime ,
2285+ componentEffectDuration ,
2286+ ) ;
2287+ }
2288+
2289+ popComponentEffectStart ( prevEffectStart ) ;
22692290}
22702291
22712292function recursivelyTraverseDisappearLayoutEffects ( parentFiber : Fiber ) {
@@ -2286,6 +2307,8 @@ export function reappearLayoutEffects(
22862307 // node was reused.
22872308 includeWorkInProgressEffects : boolean ,
22882309) {
2310+ const prevEffectStart = pushComponentEffectStart ( ) ;
2311+
22892312 // Turn on layout effects in a tree that previously disappeared.
22902313 const flags = finishedWork . flags ;
22912314 switch ( finishedWork . tag ) {
@@ -2421,6 +2444,25 @@ export function reappearLayoutEffects(
24212444 break ;
24222445 }
24232446 }
2447+
2448+ if (
2449+ enableProfilerTimer &&
2450+ enableProfilerCommitHooks &&
2451+ enableComponentPerformanceTrack &&
2452+ ( finishedWork . mode & ProfileMode ) !== NoMode &&
2453+ componentEffectStartTime >= 0 &&
2454+ componentEffectEndTime >= 0 &&
2455+ componentEffectDuration > 0.05
2456+ ) {
2457+ logComponentEffect (
2458+ finishedWork ,
2459+ componentEffectStartTime ,
2460+ componentEffectEndTime ,
2461+ componentEffectDuration ,
2462+ ) ;
2463+ }
2464+
2465+ popComponentEffectStart ( prevEffectStart ) ;
24242466}
24252467
24262468function recursivelyTraverseReappearLayoutEffects (
@@ -2846,6 +2888,7 @@ function commitPassiveMountOnFiber(
28462888 finishedWork ,
28472889 committedLanes ,
28482890 committedTransitions ,
2891+ endTime ,
28492892 ) ;
28502893 } else {
28512894 // Legacy Mode: Fire the effects even if the tree is hidden.
@@ -2884,6 +2927,7 @@ function commitPassiveMountOnFiber(
28842927 committedLanes ,
28852928 committedTransitions ,
28862929 includeWorkInProgressEffects ,
2930+ endTime ,
28872931 ) ;
28882932 }
28892933 }
@@ -2963,6 +3007,7 @@ function recursivelyTraverseReconnectPassiveEffects(
29633007 committedLanes : Lanes ,
29643008 committedTransitions : Array < Transition > | null ,
29653009 includeWorkInProgressEffects : boolean ,
3010+ endTime : number ,
29663011) {
29673012 // This function visits both newly finished work and nodes that were re-used
29683013 // from a previously committed tree. We cannot check non-static flags if the
@@ -2974,14 +3019,30 @@ function recursivelyTraverseReconnectPassiveEffects(
29743019 // TODO (Offscreen) Check: flags & (RefStatic | LayoutStatic)
29753020 let child = parentFiber . child ;
29763021 while ( child !== null ) {
2977- reconnectPassiveEffects (
2978- finishedRoot ,
2979- child ,
2980- committedLanes ,
2981- committedTransitions ,
2982- childShouldIncludeWorkInProgressEffects ,
2983- ) ;
2984- child = child . sibling ;
3022+ if ( enableProfilerTimer && enableComponentPerformanceTrack ) {
3023+ const nextSibling = child . sibling ;
3024+ reconnectPassiveEffects (
3025+ finishedRoot ,
3026+ child ,
3027+ committedLanes ,
3028+ committedTransitions ,
3029+ childShouldIncludeWorkInProgressEffects ,
3030+ nextSibling !== null
3031+ ? ( ( nextSibling . actualStartTime : any ) : number )
3032+ : endTime ,
3033+ ) ;
3034+ child = nextSibling ;
3035+ } else {
3036+ reconnectPassiveEffects (
3037+ finishedRoot ,
3038+ child ,
3039+ committedLanes ,
3040+ committedTransitions ,
3041+ childShouldIncludeWorkInProgressEffects ,
3042+ endTime ,
3043+ ) ;
3044+ child = child . sibling ;
3045+ }
29853046 }
29863047}
29873048
@@ -2994,7 +3055,28 @@ export function reconnectPassiveEffects(
29943055 // from a previously committed tree. We cannot check non-static flags if the
29953056 // node was reused.
29963057 includeWorkInProgressEffects : boolean ,
3058+ endTime : number , // Profiling-only. The start time of the next Fiber or root completion.
29973059) {
3060+ const prevEffectStart = pushComponentEffectStart ( ) ;
3061+
3062+ // If this component rendered in Profiling mode (DEV or in Profiler component) then log its
3063+ // render time. We do this after the fact in the passive effect to avoid the overhead of this
3064+ // getting in the way of the render characteristics and avoid the overhead of unwinding
3065+ // uncommitted renders.
3066+ if (
3067+ enableProfilerTimer &&
3068+ enableComponentPerformanceTrack &&
3069+ ( finishedWork . mode & ProfileMode ) !== NoMode &&
3070+ ( ( finishedWork . actualStartTime : any ) : number ) > 0 &&
3071+ ( finishedWork . flags & PerformedWork ) !== NoFlags
3072+ ) {
3073+ logComponentRender (
3074+ finishedWork ,
3075+ ( ( finishedWork . actualStartTime : any ) : number ) ,
3076+ endTime ,
3077+ ) ;
3078+ }
3079+
29983080 const flags = finishedWork . flags ;
29993081 switch ( finishedWork . tag ) {
30003082 case FunctionComponent :
@@ -3006,6 +3088,7 @@ export function reconnectPassiveEffects(
30063088 committedLanes ,
30073089 committedTransitions ,
30083090 includeWorkInProgressEffects ,
3091+ endTime ,
30093092 ) ;
30103093 // TODO: Check for PassiveStatic flag
30113094 commitHookPassiveMountEffects ( finishedWork , HookPassive ) ;
@@ -3025,6 +3108,7 @@ export function reconnectPassiveEffects(
30253108 committedLanes ,
30263109 committedTransitions ,
30273110 includeWorkInProgressEffects ,
3111+ endTime ,
30283112 ) ;
30293113
30303114 if ( includeWorkInProgressEffects && flags & Passive ) {
@@ -3051,6 +3135,7 @@ export function reconnectPassiveEffects(
30513135 committedLanes ,
30523136 committedTransitions ,
30533137 includeWorkInProgressEffects ,
3138+ endTime ,
30543139 ) ;
30553140 } else {
30563141 if ( disableLegacyMode || finishedWork . mode & ConcurrentMode ) {
@@ -3064,6 +3149,7 @@ export function reconnectPassiveEffects(
30643149 finishedWork ,
30653150 committedLanes ,
30663151 committedTransitions ,
3152+ endTime ,
30673153 ) ;
30683154 } else {
30693155 // Legacy Mode: Fire the effects even if the tree is hidden.
@@ -3074,6 +3160,7 @@ export function reconnectPassiveEffects(
30743160 committedLanes ,
30753161 committedTransitions ,
30763162 includeWorkInProgressEffects ,
3163+ endTime ,
30773164 ) ;
30783165 }
30793166 }
@@ -3093,6 +3180,7 @@ export function reconnectPassiveEffects(
30933180 committedLanes ,
30943181 committedTransitions ,
30953182 includeWorkInProgressEffects ,
3183+ endTime ,
30963184 ) ;
30973185 }
30983186
@@ -3110,6 +3198,7 @@ export function reconnectPassiveEffects(
31103198 committedLanes ,
31113199 committedTransitions ,
31123200 includeWorkInProgressEffects ,
3201+ endTime ,
31133202 ) ;
31143203 if ( includeWorkInProgressEffects && flags & Passive ) {
31153204 // TODO: Pass `current` as argument to this function
@@ -3126,6 +3215,7 @@ export function reconnectPassiveEffects(
31263215 committedLanes ,
31273216 committedTransitions ,
31283217 includeWorkInProgressEffects ,
3218+ endTime ,
31293219 ) ;
31303220 if ( includeWorkInProgressEffects && flags & Passive ) {
31313221 commitTracingMarkerPassiveMountEffect ( finishedWork ) ;
@@ -3141,17 +3231,38 @@ export function reconnectPassiveEffects(
31413231 committedLanes ,
31423232 committedTransitions ,
31433233 includeWorkInProgressEffects ,
3234+ endTime ,
31443235 ) ;
31453236 break ;
31463237 }
31473238 }
3239+
3240+ if (
3241+ enableProfilerTimer &&
3242+ enableProfilerCommitHooks &&
3243+ enableComponentPerformanceTrack &&
3244+ ( finishedWork . mode & ProfileMode ) !== NoMode &&
3245+ componentEffectStartTime >= 0 &&
3246+ componentEffectEndTime >= 0 &&
3247+ componentEffectDuration > 0.05
3248+ ) {
3249+ logComponentEffect (
3250+ finishedWork ,
3251+ componentEffectStartTime ,
3252+ componentEffectEndTime ,
3253+ componentEffectDuration ,
3254+ ) ;
3255+ }
3256+
3257+ popComponentEffectStart ( prevEffectStart ) ;
31483258}
31493259
31503260function recursivelyTraverseAtomicPassiveEffects (
31513261 finishedRoot : FiberRoot ,
31523262 parentFiber : Fiber ,
31533263 committedLanes : Lanes ,
31543264 committedTransitions : Array < Transition > | null ,
3265+ endTime : number , // Profiling-only. The start time of the next Fiber or root completion.
31553266) {
31563267 // "Atomic" effects are ones that need to fire on every commit, even during
31573268 // pre-rendering. We call this function when traversing a hidden tree whose
@@ -3160,13 +3271,28 @@ function recursivelyTraverseAtomicPassiveEffects(
31603271 if ( parentFiber . subtreeFlags & PassiveMask ) {
31613272 let child = parentFiber . child ;
31623273 while ( child !== null ) {
3163- commitAtomicPassiveEffects (
3164- finishedRoot ,
3165- child ,
3166- committedLanes ,
3167- committedTransitions ,
3168- ) ;
3169- child = child . sibling ;
3274+ if ( enableProfilerTimer && enableComponentPerformanceTrack ) {
3275+ const nextSibling = child . sibling ;
3276+ commitAtomicPassiveEffects (
3277+ finishedRoot ,
3278+ child ,
3279+ committedLanes ,
3280+ committedTransitions ,
3281+ nextSibling !== null
3282+ ? ( ( nextSibling . actualStartTime : any ) : number )
3283+ : endTime ,
3284+ ) ;
3285+ child = nextSibling ;
3286+ } else {
3287+ commitAtomicPassiveEffects (
3288+ finishedRoot ,
3289+ child ,
3290+ committedLanes ,
3291+ committedTransitions ,
3292+ endTime ,
3293+ ) ;
3294+ child = child . sibling ;
3295+ }
31703296 }
31713297 }
31723298}
@@ -3176,7 +3302,24 @@ function commitAtomicPassiveEffects(
31763302 finishedWork : Fiber ,
31773303 committedLanes : Lanes ,
31783304 committedTransitions : Array < Transition > | null ,
3305+ endTime : number , // Profiling-only. The start time of the next Fiber or root completion.
31793306) {
3307+ // If this component rendered in Profiling mode (DEV or in Profiler component) then log its
3308+ // render time. A render can happen even if the subtree is offscreen.
3309+ if (
3310+ enableProfilerTimer &&
3311+ enableComponentPerformanceTrack &&
3312+ ( finishedWork . mode & ProfileMode ) !== NoMode &&
3313+ ( ( finishedWork . actualStartTime : any ) : number ) > 0 &&
3314+ ( finishedWork . flags & PerformedWork ) !== NoFlags
3315+ ) {
3316+ logComponentRender (
3317+ finishedWork ,
3318+ ( ( finishedWork . actualStartTime : any ) : number ) ,
3319+ endTime ,
3320+ ) ;
3321+ }
3322+
31803323 // "Atomic" effects are ones that need to fire on every commit, even during
31813324 // pre-rendering. We call this function when traversing a hidden tree whose
31823325 // regular effects are currently disconnected.
@@ -3188,6 +3331,7 @@ function commitAtomicPassiveEffects(
31883331 finishedWork ,
31893332 committedLanes ,
31903333 committedTransitions ,
3334+ endTime ,
31913335 ) ;
31923336 if ( flags & Passive ) {
31933337 // TODO: Pass `current` as argument to this function
@@ -3203,6 +3347,7 @@ function commitAtomicPassiveEffects(
32033347 finishedWork ,
32043348 committedLanes ,
32053349 committedTransitions ,
3350+ endTime ,
32063351 ) ;
32073352 if ( flags & Passive ) {
32083353 // TODO: Pass `current` as argument to this function
@@ -3217,6 +3362,7 @@ function commitAtomicPassiveEffects(
32173362 finishedWork ,
32183363 committedLanes ,
32193364 committedTransitions ,
3365+ endTime ,
32203366 ) ;
32213367 break ;
32223368 }
@@ -3591,6 +3737,8 @@ function commitPassiveUnmountInsideDeletedTreeOnFiber(
35913737 current : Fiber ,
35923738 nearestMountedAncestor : Fiber | null ,
35933739) : void {
3740+ const prevEffectStart = pushComponentEffectStart ( ) ;
3741+
35943742 switch ( current . tag ) {
35953743 case FunctionComponent :
35963744 case ForwardRef :
@@ -3702,6 +3850,25 @@ function commitPassiveUnmountInsideDeletedTreeOnFiber(
37023850 break ;
37033851 }
37043852 }
3853+
3854+ if (
3855+ enableProfilerTimer &&
3856+ enableProfilerCommitHooks &&
3857+ enableComponentPerformanceTrack &&
3858+ ( current . mode & ProfileMode ) !== NoMode &&
3859+ componentEffectStartTime >= 0 &&
3860+ componentEffectEndTime >= 0 &&
3861+ componentEffectDuration > 0.05
3862+ ) {
3863+ logComponentEffect (
3864+ current ,
3865+ componentEffectStartTime ,
3866+ componentEffectEndTime ,
3867+ componentEffectDuration ,
3868+ ) ;
3869+ }
3870+
3871+ popComponentEffectStart ( prevEffectStart ) ;
37053872}
37063873
37073874export function invokeLayoutEffectMountInDEV ( fiber : Fiber ) : void {
0 commit comments