@samitouri / QOS-React / commits / dab0854c5e

Move commit passive unmount/mount to CommitWork (#19599)

Sebastian Markbåge committed Aug 13, 2020 at 12:17 UTC dab0854c5e66ca74ca0591fd312d6a654e5aaaf1
2 files changed +172 -152
packages/react-reconciler/src/ReactFiberCommitWork.new.js
+159 -4
@@ -20,10 +20,14 @@ import type {FiberRoot} from './ReactInternalTypes';
20 import type {Lanes} from './ReactFiberLane';
21 import type {SuspenseState} from './ReactFiberSuspenseComponent.new';
22 import type {UpdateQueue} from './ReactUpdateQueue.new';
23 -import type {FunctionComponentUpdateQueue} from './ReactFiberHooks.new';
23 +import type {
24 + Effect as HookEffect,
25 + FunctionComponentUpdateQueue,
26 +} from './ReactFiberHooks.new';
27 import type {Wakeable} from 'shared/ReactTypes';
28 import type {ReactPriorityLevel} from './ReactInternalTypes';
29 import type {OffscreenState} from './ReactFiberOffscreenComponent';
30 +import type {HookEffectTag} from './ReactHookEffectTags';
31
32 import {unstable_wrap as Schedule_tracing_wrap} from 'scheduler/tracing';
33 import {
@@ -77,6 +81,8 @@ import {
81 getCommitTime,
82 recordLayoutEffectDuration,
83 startLayoutEffectTimer,
84 + recordPassiveEffectDuration,
85 + startPassiveEffectTimer,
86 } from './ReactProfilerTimer.new';
87 import {ProfileMode} from './ReactTypeOfMode';
88 import {commitUpdateQueue} from './ReactUpdateQueue.new';
@@ -121,6 +127,7 @@ import {
127 NoEffect as NoHookEffect,
128 HasEffect as HookHasEffect,
129 Layout as HookLayout,
130 + Passive as HookPassive,
131 } from './ReactHookEffectTags';
132 import {didWarnAboutReassigningProps} from './ReactFiberBeginWork.new';
133 import {
@@ -308,7 +315,7 @@ function commitBeforeMutationLifeCycles(
315 );
316 }
317
311 -function commitHookEffectListUnmount(tag: number, finishedWork: Fiber) {
318 +function commitHookEffectListUnmount(tag: HookEffectTag, finishedWork: Fiber) {
319 const updateQueue: FunctionComponentUpdateQueue | null = (finishedWork.updateQueue: any);
320 const lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
321 if (lastEffect !== null) {
@@ -328,7 +335,43 @@ function commitHookEffectListUnmount(tag: number, finishedWork: Fiber) {
335 }
336 }
337
331 -function commitHookEffectListMount(tag: number, finishedWork: Fiber) {
338 +// TODO: Remove this duplication.
339 +function commitHookEffectListUnmount2(
340 + // Tags to check for when deciding whether to unmount. e.g. to skip over
341 + // layout effects
342 + hookEffectTag: HookEffectTag,
343 + fiber: Fiber,
344 +): void {
345 + const updateQueue: FunctionComponentUpdateQueue | null = (fiber.updateQueue: any);
346 + const lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
347 + if (lastEffect !== null) {
348 + const firstEffect = lastEffect.next;
349 + let effect = firstEffect;
350 + do {
351 + const {next, tag} = effect;
352 + if ((tag & hookEffectTag) === hookEffectTag) {
353 + const destroy = effect.destroy;
354 + if (destroy !== undefined) {
355 + effect.destroy = undefined;
356 + if (
357 + enableProfilerTimer &&
358 + enableProfilerCommitHooks &&
359 + fiber.mode & ProfileMode
360 + ) {
361 + startPassiveEffectTimer();
362 + safelyCallDestroy(fiber, destroy);
363 + recordPassiveEffectDuration(fiber);
364 + } else {
365 + safelyCallDestroy(fiber, destroy);
366 + }
367 + }
368 + }
369 + effect = next;
370 + } while (effect !== firstEffect);
371 + }
372 +}
373 +
374 +function commitHookEffectListMount(tag: HookEffectTag, finishedWork: Fiber) {
375 const updateQueue: FunctionComponentUpdateQueue | null = (finishedWork.updateQueue: any);
376 const lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
377 if (lastEffect !== null) {
@@ -378,6 +421,83 @@ function commitHookEffectListMount(tag: number, finishedWork: Fiber) {
421 }
422 }
423
424 +function invokePassiveEffectCreate(effect: HookEffect): void {
425 + const create = effect.create;
426 + effect.destroy = create();
427 +}
428 +
429 +// TODO: Remove this duplication.
430 +function commitHookEffectListMount2(fiber: Fiber): void {
431 + const updateQueue: FunctionComponentUpdateQueue | null = (fiber.updateQueue: any);
432 + const lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
433 + if (lastEffect !== null) {
434 + const firstEffect = lastEffect.next;
435 + let effect = firstEffect;
436 + do {
437 + const {next, tag} = effect;
438 +
439 + if (
440 + (tag & HookPassive) !== NoHookEffect &&
441 + (tag & HookHasEffect) !== NoHookEffect
442 + ) {
443 + if (__DEV__) {
444 + if (
445 + enableProfilerTimer &&
446 + enableProfilerCommitHooks &&
447 + fiber.mode & ProfileMode
448 + ) {
449 + startPassiveEffectTimer();
450 + invokeGuardedCallback(
451 + null,
452 + invokePassiveEffectCreate,
453 + null,
454 + effect,
455 + );
456 + recordPassiveEffectDuration(fiber);
457 + } else {
458 + invokeGuardedCallback(
459 + null,
460 + invokePassiveEffectCreate,
461 + null,
462 + effect,
463 + );
464 + }
465 + if (hasCaughtError()) {
466 + invariant(fiber !== null, 'Should be working on an effect.');
467 + const error = clearCaughtError();
468 + captureCommitPhaseError(fiber, error);
469 + }
470 + } else {
471 + try {
472 + const create = effect.create;
473 + if (
474 + enableProfilerTimer &&
475 + enableProfilerCommitHooks &&
476 + fiber.mode & ProfileMode
477 + ) {
478 + try {
479 + startPassiveEffectTimer();
480 + effect.destroy = create();
481 + } finally {
482 + recordPassiveEffectDuration(fiber);
483 + }
484 + } else {
485 + effect.destroy = create();
486 + }
487 + // TODO: This is missing the warning that exists in commitHookEffectListMount.
488 + // The warning refers to useEffect but only applies to useLayoutEffect.
489 + } catch (error) {
490 + invariant(fiber !== null, 'Should be working on an effect.');
491 + captureCommitPhaseError(fiber, error);
492 + }
493 + }
494 + }
495 +
496 + effect = next;
497 + } while (effect !== firstEffect);
498 + }
499 +}
500 +
501 export function commitPassiveEffectDurations(
502 finishedRoot: FiberRoot,
503 finishedWork: Fiber,
@@ -1709,13 +1829,45 @@ export function isSuspenseBoundaryBeingHidden(
1829 return false;
1830 }
1831
1712 -function commitResetTextContent(current: Fiber) {
1832 +function commitResetTextContent(current: Fiber): void {
1833 if (!supportsMutation) {
1834 return;
1835 }
1836 resetTextContent(current.stateNode);
1837 }
1838
1839 +function commitPassiveWork(finishedWork: Fiber): void {
1840 + switch (finishedWork.tag) {
1841 + case FunctionComponent:
1842 + case ForwardRef:
1843 + case SimpleMemoComponent:
1844 + case Block: {
1845 + commitHookEffectListUnmount2(HookPassive | HookHasEffect, finishedWork);
1846 + }
1847 + }
1848 +}
1849 +
1850 +function commitPassiveUnmount(current: Fiber): void {
1851 + switch (current.tag) {
1852 + case FunctionComponent:
1853 + case ForwardRef:
1854 + case SimpleMemoComponent:
1855 + case Block:
1856 + commitHookEffectListUnmount2(HookPassive, current);
1857 + }
1858 +}
1859 +
1860 +function commitPassiveLifeCycles(finishedWork: Fiber): void {
1861 + switch (finishedWork.tag) {
1862 + case FunctionComponent:
1863 + case ForwardRef:
1864 + case SimpleMemoComponent:
1865 + case Block: {
1866 + commitHookEffectListMount2(finishedWork);
1867 + }
1868 + }
1869 +}
1870 +
1871 export {
1872 commitBeforeMutationLifeCycles,
1873 commitResetTextContent,
@@ -1725,4 +1877,7 @@ export {
1877 commitLifeCycles,
1878 commitAttachRef,
1879 commitDetachRef,
1880 + commitPassiveUnmount,
1881 + commitPassiveWork,
1882 + commitPassiveLifeCycles,
1883 };
packages/react-reconciler/src/ReactFiberWorkLoop.new.js
+13 -148
@@ -14,8 +14,6 @@ import type {ReactPriorityLevel} from './ReactInternalTypes';
14 import type {Interaction} from 'scheduler/src/Tracing';
15 import type {SuspenseConfig} from './ReactFiberSuspenseConfig';
16 import type {SuspenseState} from './ReactFiberSuspenseComponent.new';
17 -import type {Effect as HookEffect} from './ReactFiberHooks.new';
18 -import type {HookEffectTag} from './ReactHookEffectTags';
17 import type {StackCursor} from './ReactFiberStack.new';
18 import type {FunctionComponentUpdateQueue} from './ReactFiberHooks.new';
19
@@ -53,7 +51,6 @@ import {
51 } from './SchedulerWithReactIntegration.new';
52 import {
53 NoEffect as NoHookEffect,
56 - HasEffect as HookHasEffect,
54 Passive as HookPassive,
55 } from './ReactHookEffectTags';
56 import {
@@ -206,12 +203,14 @@ import {
203 commitPlacement,
204 commitWork,
205 commitDeletion,
206 + commitPassiveUnmount,
207 + commitPassiveWork,
208 + commitPassiveLifeCycles as commitPassiveEffectOnFiber,
209 commitDetachRef,
210 commitAttachRef,
211 commitPassiveEffectDurations,
212 commitResetTextContent,
213 isSuspenseBoundaryBeingHidden,
214 - safelyCallDestroy,
214 } from './ReactFiberCommitWork.new';
215 import {enqueueUpdate} from './ReactUpdateQueue.new';
216 import {resetContextDependencies} from './ReactFiberNewContext.new';
@@ -229,8 +228,6 @@ import {
228
229 import {
230 recordCommitTime,
232 - recordPassiveEffectDuration,
233 - startPassiveEffectTimer,
231 startProfilerTimer,
232 stopProfilerTimerIfRunningAndRecordDelta,
233 } from './ReactProfilerTimer.new';
@@ -2738,11 +2735,6 @@ export function enqueuePendingPassiveProfilerEffect(fiber: Fiber): void {
2735 }
2736 }
2737
2741 -function invokePassiveEffectCreate(effect: HookEffect): void {
2742 - const create = effect.create;
2743 - effect.destroy = create();
2744 -}
2745 -
2738 function flushPassiveMountEffects(firstChild: Fiber): void {
2739 let fiber = firstChild;
2740 while (fiber !== null) {
@@ -2753,93 +2745,15 @@ function flushPassiveMountEffects(firstChild: Fiber): void {
2745 }
2746
2747 if ((fiber.effectTag & Update) !== NoEffect) {
2756 - switch (fiber.tag) {
2757 - case FunctionComponent:
2758 - case ForwardRef:
2759 - case SimpleMemoComponent:
2760 - case Block: {
2761 - flushPassiveMountEffectsImpl(fiber);
2762 - }
2763 - }
2748 + setCurrentDebugFiberInDEV(fiber);
2749 + commitPassiveEffectOnFiber(fiber);
2750 + resetCurrentDebugFiberInDEV();
2751 }
2752
2753 fiber = fiber.sibling;
2754 }
2755 }
2756
2770 -function flushPassiveMountEffectsImpl(fiber: Fiber): void {
2771 - setCurrentDebugFiberInDEV(fiber);
2772 -
2773 - const updateQueue: FunctionComponentUpdateQueue | null = (fiber.updateQueue: any);
2774 - const lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
2775 - if (lastEffect !== null) {
2776 - const firstEffect = lastEffect.next;
2777 - let effect = firstEffect;
2778 - do {
2779 - const {next, tag} = effect;
2780 -
2781 - if (
2782 - (tag & HookPassive) !== NoHookEffect &&
2783 - (tag & HookHasEffect) !== NoHookEffect
2784 - ) {
2785 - if (__DEV__) {
2786 - if (
2787 - enableProfilerTimer &&
2788 - enableProfilerCommitHooks &&
2789 - fiber.mode & ProfileMode
2790 - ) {
2791 - startPassiveEffectTimer();
2792 - invokeGuardedCallback(
2793 - null,
2794 - invokePassiveEffectCreate,
2795 - null,
2796 - effect,
2797 - );
2798 - recordPassiveEffectDuration(fiber);
2799 - } else {
2800 - invokeGuardedCallback(
2801 - null,
2802 - invokePassiveEffectCreate,
2803 - null,
2804 - effect,
2805 - );
2806 - }
2807 - if (hasCaughtError()) {
2808 - invariant(fiber !== null, 'Should be working on an effect.');
2809 - const error = clearCaughtError();
2810 - captureCommitPhaseError(fiber, error);
2811 - }
2812 - } else {
2813 - try {
2814 - const create = effect.create;
2815 - if (
2816 - enableProfilerTimer &&
2817 - enableProfilerCommitHooks &&
2818 - fiber.mode & ProfileMode
2819 - ) {
2820 - try {
2821 - startPassiveEffectTimer();
2822 - effect.destroy = create();
2823 - } finally {
2824 - recordPassiveEffectDuration(fiber);
2825 - }
2826 - } else {
2827 - effect.destroy = create();
2828 - }
2829 - } catch (error) {
2830 - invariant(fiber !== null, 'Should be working on an effect.');
2831 - captureCommitPhaseError(fiber, error);
2832 - }
2833 - }
2834 - }
2835 -
2836 - effect = next;
2837 - } while (effect !== firstEffect);
2838 -
2839 - resetCurrentDebugFiberInDEV();
2840 - }
2841 -}
2842 -
2757 function flushPassiveUnmountEffects(firstChild: Fiber): void {
2758 let fiber = firstChild;
2759 while (fiber !== null) {
@@ -2866,16 +2780,11 @@ function flushPassiveUnmountEffects(firstChild: Fiber): void {
2780 }
2781 }
2782
2869 - switch (fiber.tag) {
2870 - case FunctionComponent:
2871 - case ForwardRef:
2872 - case SimpleMemoComponent:
2873 - case Block: {
2874 - const primaryEffectTag = fiber.effectTag & Passive;
2875 - if (primaryEffectTag !== NoEffect) {
2876 - flushPassiveUnmountEffectsImpl(fiber, HookPassive | HookHasEffect);
2877 - }
2878 - }
2783 + const primaryEffectTag = fiber.effectTag & Passive;
2784 + if (primaryEffectTag !== NoEffect) {
2785 + setCurrentDebugFiberInDEV(fiber);
2786 + commitPassiveWork(fiber);
2787 + resetCurrentDebugFiberInDEV();
2788 }
2789
2790 fiber = fiber.sibling;
@@ -2898,52 +2807,8 @@ function flushPassiveUnmountEffectsInsideOfDeletedTree(
2807 }
2808
2809 if ((fiberToDelete.effectTag & PassiveStatic) !== NoEffect) {
2901 - switch (fiberToDelete.tag) {
2902 - case FunctionComponent:
2903 - case ForwardRef:
2904 - case SimpleMemoComponent:
2905 - case Block: {
2906 - flushPassiveUnmountEffectsImpl(fiberToDelete, HookPassive);
2907 - }
2908 - }
2909 - }
2910 -}
2911 -
2912 -function flushPassiveUnmountEffectsImpl(
2913 - fiber: Fiber,
2914 - // Tags to check for when deciding whether to unmount. e.g. to skip over
2915 - // layout effects
2916 - hookEffectTag: HookEffectTag,
2917 -): void {
2918 - const updateQueue: FunctionComponentUpdateQueue | null = (fiber.updateQueue: any);
2919 - const lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
2920 - if (lastEffect !== null) {
2921 - setCurrentDebugFiberInDEV(fiber);
2922 -
2923 - const firstEffect = lastEffect.next;
2924 - let effect = firstEffect;
2925 - do {
2926 - const {next, tag} = effect;
2927 - if ((tag & hookEffectTag) === hookEffectTag) {
2928 - const destroy = effect.destroy;
2929 - if (destroy !== undefined) {
2930 - effect.destroy = undefined;
2931 - if (
2932 - enableProfilerTimer &&
2933 - enableProfilerCommitHooks &&
2934 - fiber.mode & ProfileMode
2935 - ) {
2936 - startPassiveEffectTimer();
2937 - safelyCallDestroy(fiber, destroy);
2938 - recordPassiveEffectDuration(fiber);
2939 - } else {
2940 - safelyCallDestroy(fiber, destroy);
2941 - }
2942 - }
2943 - }
2944 - effect = next;
2945 - } while (effect !== firstEffect);
2946 -
2810 + setCurrentDebugFiberInDEV(fiberToDelete);
2811 + commitPassiveUnmount(fiberToDelete);
2812 resetCurrentDebugFiberInDEV();
2813 }
2814 }