119
resetComponentEffectTimers,
120
pushComponentEffectStart,
121
popComponentEffectStart,
122
+ pushComponentEffectDuration,
123
+ popComponentEffectDuration,
124
pushComponentEffectErrors,
125
popComponentEffectErrors,
126
componentEffectStartTime,
545
committedLanes: Lanes,
546
): void {
547
const prevEffectStart = pushComponentEffectStart();
548
+ const prevEffectDuration = pushComponentEffectDuration();
549
const prevEffectErrors = pushComponentEffectErrors();
550
// When updating this function, also update reappearLayoutEffects, which does
551
// most of the same things when an offscreen tree goes from hidden -> visible.
584
break;
585
}
586
case HostRoot: {
584
- const prevEffectDuration = pushNestedEffectDurations();
587
+ const prevProfilerEffectDuration = pushNestedEffectDurations();
588
recursivelyTraverseLayoutEffects(
589
finishedRoot,
590
finishedWork,
594
commitRootCallbacks(finishedWork);
595
}
596
if (enableProfilerTimer && enableProfilerCommitHooks) {
594
- finishedRoot.effectDuration +=
595
- popNestedEffectDurations(prevEffectDuration);
597
+ finishedRoot.effectDuration += popNestedEffectDurations(
598
+ prevProfilerEffectDuration,
599
+ );
600
}
601
break;
602
}
642
// TODO: Should this fire inside an offscreen tree? Or should it wait to
643
// fire when the tree becomes visible again.
644
if (flags & Update) {
641
- const prevEffectDuration = pushNestedEffectDurations();
645
+ const prevProfilerEffectDuration = pushNestedEffectDurations();
646
647
recursivelyTraverseLayoutEffects(
648
finishedRoot,
655
if (enableProfilerTimer && enableProfilerCommitHooks) {
656
// Propagate layout effect durations to the next nearest Profiler ancestor.
657
// Do not reset these values until the next render so DevTools has a chance to read them first.
654
- profilerInstance.effectDuration +=
655
- bubbleNestedEffectDurations(prevEffectDuration);
658
+ profilerInstance.effectDuration += bubbleNestedEffectDurations(
659
+ prevProfilerEffectDuration,
660
+ );
661
}
662
663
commitProfilerUpdate(
809
}
810
811
popComponentEffectStart(prevEffectStart);
812
+ popComponentEffectDuration(prevEffectDuration);
813
popComponentEffectErrors(prevEffectErrors);
814
}
815
1306
// TODO: Delete this Hook once new DevTools ships everywhere. No longer needed.
1307
onCommitUnmount(deletedFiber);
1308
1309
+ const prevEffectStart = pushComponentEffectStart();
1310
+ const prevEffectDuration = pushComponentEffectDuration();
1311
+ const prevEffectErrors = pushComponentEffectErrors();
1312
+
1313
// The cases in this outer switch modify the stack before they traverse
1314
// into their subtree. There are simpler cases in the inner switch
1315
// that don't modify the stack.
1329
} else if (deletedFiber.stateNode) {
1330
unmountHoistable(deletedFiber.stateNode);
1331
}
1322
- return;
1332
+ break;
1333
}
1334
// Fall through
1335
}
1361
hostParent = prevHostParent;
1362
hostParentIsContainer = prevHostParentIsContainer;
1363
1354
- return;
1364
+ break;
1365
}
1366
// Fall through
1367
}
1416
deletedFiber,
1417
);
1418
}
1409
- return;
1419
+ break;
1420
}
1421
case DehydratedFragment: {
1422
if (enableSuspenseCallback) {
1455
}
1456
}
1457
}
1448
- return;
1458
+ break;
1459
}
1460
case HostPortal: {
1461
if (supportsMutation) {
1486
deletedFiber,
1487
);
1488
}
1479
- return;
1489
+ break;
1490
}
1491
case FunctionComponent:
1492
case ForwardRef:
1515
nearestMountedAncestor,
1516
deletedFiber,
1517
);
1508
- return;
1518
+ break;
1519
}
1520
case ClassComponent: {
1521
if (!offscreenSubtreeWasHidden) {
1534
nearestMountedAncestor,
1535
deletedFiber,
1536
);
1527
- return;
1537
+ break;
1538
}
1539
case ScopeComponent: {
1540
if (enableScopeAPI) {
1547
nearestMountedAncestor,
1548
deletedFiber,
1549
);
1540
- return;
1550
+ break;
1551
}
1552
case OffscreenComponent: {
1553
if (disableLegacyMode || deletedFiber.mode & ConcurrentMode) {
1592
nearestMountedAncestor,
1593
deletedFiber,
1594
);
1585
- return;
1595
+ break;
1596
}
1597
// Fallthrough
1598
}
1606
nearestMountedAncestor,
1607
deletedFiber,
1608
);
1599
- return;
1609
+ break;
1610
}
1611
// Fallthrough
1612
}
1616
nearestMountedAncestor,
1617
deletedFiber,
1618
);
1609
- return;
1619
+ break;
1620
}
1621
}
1622
+
1623
+ if (
1624
+ enableProfilerTimer &&
1625
+ enableProfilerCommitHooks &&
1626
+ enableComponentPerformanceTrack &&
1627
+ (deletedFiber.mode & ProfileMode) !== NoMode &&
1628
+ componentEffectStartTime >= 0 &&
1629
+ componentEffectEndTime >= 0 &&
1630
+ componentEffectDuration > 0.05
1631
+ ) {
1632
+ logComponentEffect(
1633
+ deletedFiber,
1634
+ componentEffectStartTime,
1635
+ componentEffectEndTime,
1636
+ componentEffectDuration,
1637
+ componentEffectErrors,
1638
+ );
1639
+ }
1640
+
1641
+ popComponentEffectStart(prevEffectStart);
1642
+ popComponentEffectDuration(prevEffectDuration);
1643
+ popComponentEffectErrors(prevEffectErrors);
1644
}
1645
+
1646
function commitSuspenseCallback(finishedWork: Fiber) {
1647
// TODO: Delete this feature. It's not properly covered by DEV features.
1648
const newState: SuspenseState | null = finishedWork.memoizedState;
1829
lanes: Lanes,
1830
) {
1831
const prevEffectStart = pushComponentEffectStart();
1832
+ const prevEffectDuration = pushComponentEffectDuration();
1833
const prevEffectErrors = pushComponentEffectErrors();
1834
const current = finishedWork.alternate;
1835
const flags = finishedWork.flags;
2053
break;
2054
}
2055
case HostRoot: {
2022
- const prevEffectDuration = pushNestedEffectDurations();
2056
+ const prevProfilerEffectDuration = pushNestedEffectDurations();
2057
2058
if (supportsResources) {
2059
prepareToCommitHoistables();
2099
}
2100
2101
if (enableProfilerTimer && enableProfilerCommitHooks) {
2068
- root.effectDuration += popNestedEffectDurations(prevEffectDuration);
2102
+ root.effectDuration += popNestedEffectDurations(
2103
+ prevProfilerEffectDuration,
2104
+ );
2105
}
2106
2107
break;
2141
break;
2142
}
2143
case Profiler: {
2108
- const prevEffectDuration = pushNestedEffectDurations();
2144
+ const prevProfilerEffectDuration = pushNestedEffectDurations();
2145
2146
recursivelyTraverseMutationEffects(root, finishedWork, lanes);
2147
commitReconciliationEffects(finishedWork, lanes);
2150
const profilerInstance = finishedWork.stateNode;
2151
// Propagate layout effect durations to the next nearest Profiler ancestor.
2152
// Do not reset these values until the next render so DevTools has a chance to read them first.
2117
- profilerInstance.effectDuration +=
2118
- bubbleNestedEffectDurations(prevEffectDuration);
2153
+ profilerInstance.effectDuration += bubbleNestedEffectDurations(
2154
+ prevProfilerEffectDuration,
2155
+ );
2156
}
2157
break;
2158
}
2384
}
2385
2386
popComponentEffectStart(prevEffectStart);
2387
+ popComponentEffectDuration(prevEffectDuration);
2388
popComponentEffectErrors(prevEffectErrors);
2389
}
2390
2636
2637
export function disappearLayoutEffects(finishedWork: Fiber) {
2638
const prevEffectStart = pushComponentEffectStart();
2639
+ const prevEffectDuration = pushComponentEffectDuration();
2640
const prevEffectErrors = pushComponentEffectErrors();
2641
switch (finishedWork.tag) {
2642
case FunctionComponent:
2740
}
2741
2742
popComponentEffectStart(prevEffectStart);
2743
+ popComponentEffectDuration(prevEffectDuration);
2744
popComponentEffectErrors(prevEffectErrors);
2745
}
2746
2763
includeWorkInProgressEffects: boolean,
2764
) {
2765
const prevEffectStart = pushComponentEffectStart();
2766
+ const prevEffectDuration = pushComponentEffectDuration();
2767
const prevEffectErrors = pushComponentEffectErrors();
2768
// Turn on layout effects in a tree that previously disappeared.
2769
const flags = finishedWork.flags;
2847
case Profiler: {
2848
// TODO: Figure out how Profiler updates should work with Offscreen
2849
if (includeWorkInProgressEffects && flags & Update) {
2809
- const prevEffectDuration = pushNestedEffectDurations();
2850
+ const prevProfilerEffectDuration = pushNestedEffectDurations();
2851
2852
recursivelyTraverseReappearLayoutEffects(
2853
finishedRoot,
2860
if (enableProfilerTimer && enableProfilerCommitHooks) {
2861
// Propagate layout effect durations to the next nearest Profiler ancestor.
2862
// Do not reset these values until the next render so DevTools has a chance to read them first.
2822
- profilerInstance.effectDuration +=
2823
- bubbleNestedEffectDurations(prevEffectDuration);
2863
+ profilerInstance.effectDuration += bubbleNestedEffectDurations(
2864
+ prevProfilerEffectDuration,
2865
+ );
2866
}
2867
2868
commitProfilerUpdate(
2961
}
2962
2963
popComponentEffectStart(prevEffectStart);
2964
+ popComponentEffectDuration(prevEffectDuration);
2965
popComponentEffectErrors(prevEffectErrors);
2966
}
2967
3212
endTime: number, // Profiling-only. The start time of the next Fiber or root completion.
3213
): void {
3214
const prevEffectStart = pushComponentEffectStart();
3215
+ const prevEffectDuration = pushComponentEffectDuration();
3216
const prevEffectErrors = pushComponentEffectErrors();
3217
3218
const isViewTransitionEligible = enableViewTransition
3316
break;
3317
}
3318
case HostRoot: {
3275
- const prevEffectDuration = pushNestedEffectDurations();
3319
+ const prevProfilerEffectDuration = pushNestedEffectDurations();
3320
3321
const wasInHydratedSubtree = inHydratedSubtree;
3322
if (enableProfilerTimer && enableComponentPerformanceTrack) {
3393
}
3394
}
3395
if (enableProfilerTimer && enableProfilerCommitHooks) {
3352
- finishedRoot.passiveEffectDuration +=
3353
- popNestedEffectDurations(prevEffectDuration);
3396
+ finishedRoot.passiveEffectDuration += popNestedEffectDurations(
3397
+ prevProfilerEffectDuration,
3398
+ );
3399
}
3400
break;
3401
}
3402
case Profiler: {
3403
// Only Profilers with work in their subtree will have a Passive effect scheduled.
3404
if (flags & Passive) {
3360
- const prevEffectDuration = pushNestedEffectDurations();
3405
+ const prevProfilerEffectDuration = pushNestedEffectDurations();
3406
3407
recursivelyTraversePassiveMountEffects(
3408
finishedRoot,
3417
if (enableProfilerTimer && enableProfilerCommitHooks) {
3418
// Bubble times to the next nearest ancestor Profiler.
3419
// After we process that Profiler, we'll bubble further up.
3375
- profilerInstance.passiveEffectDuration +=
3376
- bubbleNestedEffectDurations(prevEffectDuration);
3420
+ profilerInstance.passiveEffectDuration += bubbleNestedEffectDurations(
3421
+ prevProfilerEffectDuration,
3422
+ );
3423
}
3424
3425
commitProfilerPostCommit(
3703
}
3704
3705
popComponentEffectStart(prevEffectStart);
3706
+ popComponentEffectDuration(prevEffectDuration);
3707
popComponentEffectErrors(prevEffectErrors);
3708
}
3709
3764
endTime: number, // Profiling-only. The start time of the next Fiber or root completion.
3765
) {
3766
const prevEffectStart = pushComponentEffectStart();
3767
+ const prevEffectDuration = pushComponentEffectDuration();
3768
const prevEffectErrors = pushComponentEffectErrors();
3769
// If this component rendered in Profiling mode (DEV or in Profiler component) then log its
3770
// render time. We do this after the fact in the passive effect to avoid the overhead of this
3964
}
3965
3966
popComponentEffectStart(prevEffectStart);
3967
+ popComponentEffectDuration(prevEffectDuration);
3968
popComponentEffectErrors(prevEffectErrors);
3969
}
3970
4267
4268
function commitPassiveUnmountOnFiber(finishedWork: Fiber): void {
4269
const prevEffectStart = pushComponentEffectStart();
4270
+ const prevEffectDuration = pushComponentEffectDuration();
4271
const prevEffectErrors = pushComponentEffectErrors();
4272
switch (finishedWork.tag) {
4273
case FunctionComponent:
4284
break;
4285
}
4286
case HostRoot: {
4237
- const prevEffectDuration = pushNestedEffectDurations();
4287
+ const prevProfilerEffectDuration = pushNestedEffectDurations();
4288
recursivelyTraversePassiveUnmountEffects(finishedWork);
4289
if (enableProfilerTimer && enableProfilerCommitHooks) {
4290
const finishedRoot: FiberRoot = finishedWork.stateNode;
4241
- finishedRoot.passiveEffectDuration +=
4242
- popNestedEffectDurations(prevEffectDuration);
4291
+ finishedRoot.passiveEffectDuration += popNestedEffectDurations(
4292
+ prevProfilerEffectDuration,
4293
+ );
4294
}
4295
break;
4296
}
4297
case Profiler: {
4247
- const prevEffectDuration = pushNestedEffectDurations();
4298
+ const prevProfilerEffectDuration = pushNestedEffectDurations();
4299
4300
recursivelyTraversePassiveUnmountEffects(finishedWork);
4301
4303
const profilerInstance = finishedWork.stateNode;
4304
// Propagate layout effect durations to the next nearest Profiler ancestor.
4305
// Do not reset these values until the next render so DevTools has a chance to read them first.
4255
- profilerInstance.passiveEffectDuration +=
4256
- bubbleNestedEffectDurations(prevEffectDuration);
4306
+ profilerInstance.passiveEffectDuration += bubbleNestedEffectDurations(
4307
+ prevProfilerEffectDuration,
4308
+ );
4309
}
4310
break;
4311
}
4360
}
4361
4362
popComponentEffectStart(prevEffectStart);
4363
+ popComponentEffectDuration(prevEffectDuration);
4364
popComponentEffectErrors(prevEffectErrors);
4365
}
4366
4393
}
4394
4395
export function disconnectPassiveEffect(finishedWork: Fiber): void {
4396
+ const prevEffectStart = pushComponentEffectStart();
4397
+ const prevEffectDuration = pushComponentEffectDuration();
4398
+ const prevEffectErrors = pushComponentEffectErrors();
4399
+
4400
switch (finishedWork.tag) {
4401
case FunctionComponent:
4402
case ForwardRef:
4427
break;
4428
}
4429
}
4430
+
4431
+ if (
4432
+ enableProfilerTimer &&
4433
+ enableProfilerCommitHooks &&
4434
+ enableComponentPerformanceTrack &&
4435
+ (finishedWork.mode & ProfileMode) !== NoMode &&
4436
+ componentEffectStartTime >= 0 &&
4437
+ componentEffectEndTime >= 0 &&
4438
+ componentEffectDuration > 0.05
4439
+ ) {
4440
+ logComponentEffect(
4441
+ finishedWork,
4442
+ componentEffectStartTime,
4443
+ componentEffectEndTime,
4444
+ componentEffectDuration,
4445
+ componentEffectErrors,
4446
+ );
4447
+ }
4448
+
4449
+ popComponentEffectStart(prevEffectStart);
4450
+ popComponentEffectDuration(prevEffectDuration);
4451
+ popComponentEffectErrors(prevEffectErrors);
4452
}
4453
4454
function commitPassiveUnmountEffectsInsideOfDeletedTree_begin(
4507
nearestMountedAncestor: Fiber | null,
4508
): void {
4509
const prevEffectStart = pushComponentEffectStart();
4510
+ const prevEffectDuration = pushComponentEffectDuration();
4511
const prevEffectErrors = pushComponentEffectErrors();
4512
switch (current.tag) {
4513
case FunctionComponent:
4640
}
4641
4642
popComponentEffectStart(prevEffectStart);
4643
+ popComponentEffectDuration(prevEffectDuration);
4644
popComponentEffectErrors(prevEffectErrors);
4645
}
4646