Skip to content

Commit

Permalink
offscreen double invoke effects
Browse files Browse the repository at this point in the history
  • Loading branch information
lunaruan committed Aug 4, 2020
1 parent 5f1890f commit c927a2c
Show file tree
Hide file tree
Showing 14 changed files with 452 additions and 100 deletions.
104 changes: 54 additions & 50 deletions packages/react-reconciler/src/ReactFiberCommitWork.new.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import {
enableFundamentalAPI,
enableSuspenseCallback,
enableScopeAPI,
enableDoubleInvokingEffects,
} from 'shared/ReactFeatureFlags';
import {
FunctionComponent,
Expand Down Expand Up @@ -313,7 +314,8 @@ function commitBeforeMutationLifeCycles(
);
}

function commitHookEffectListUnmount(tag: number, finishedWork: Fiber) {
function commitHookLayoutEffectListUnmount(finishedWork: Fiber) {
const tag = HookLayout | HookHasEffect;
const updateQueue: FunctionComponentUpdateQueue | null = (finishedWork.updateQueue: any);
const lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
if (lastEffect !== null) {
Expand All @@ -325,15 +327,29 @@ function commitHookEffectListUnmount(tag: number, finishedWork: Fiber) {
const destroy = effect.destroy;
effect.destroy = undefined;
if (destroy !== undefined) {
destroy();
if (
enableProfilerTimer &&
enableProfilerCommitHooks &&
finishedWork.mode & ProfileMode
) {
try {
startLayoutEffectTimer();
destroy();
} finally {
recordLayoutEffectDuration(finishedWork);
}
} else {
destroy();
}
}
}
effect = effect.next;
} while (effect !== firstEffect);
}
}

function commitHookEffectListMount(tag: number, finishedWork: Fiber) {
function commitHookLayoutEffectListMount(finishedWork: Fiber) {
const tag = HookLayout | HookHasEffect;
const updateQueue: FunctionComponentUpdateQueue | null = (finishedWork.updateQueue: any);
const lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
if (lastEffect !== null) {
Expand All @@ -343,8 +359,20 @@ function commitHookEffectListMount(tag: number, finishedWork: Fiber) {
if ((effect.tag & tag) === tag) {
// Mount
const create = effect.create;
effect.destroy = create();

if (
enableProfilerTimer &&
enableProfilerCommitHooks &&
finishedWork.mode & ProfileMode
) {
try {
startLayoutEffectTimer();
effect.destroy = create();
} finally {
recordLayoutEffectDuration(finishedWork);
}
} else {
effect.destroy = create();
}
if (__DEV__) {
const destroy = effect.destroy;
if (destroy !== undefined && typeof destroy !== 'function') {
Expand Down Expand Up @@ -376,6 +404,14 @@ function commitHookEffectListMount(tag: number, finishedWork: Fiber) {
addendum,
);
}

if (enableDoubleInvokingEffects) {
effect.destroy = undefined;
if (typeof destroy === 'function') {
destroy();
}
effect.destroy = create();
}
}
}
effect = effect.next;
Expand Down Expand Up @@ -453,20 +489,7 @@ function commitLifeCycles(
// This is done to prevent sibling component effects from interfering with each other,
// e.g. a destroy function in one component should never override a ref set
// by a create function in another component during the same commit.
if (
enableProfilerTimer &&
enableProfilerCommitHooks &&
finishedWork.mode & ProfileMode
) {
try {
startLayoutEffectTimer();
commitHookEffectListMount(HookLayout | HookHasEffect, finishedWork);
} finally {
recordLayoutEffectDuration(finishedWork);
}
} else {
commitHookEffectListMount(HookLayout | HookHasEffect, finishedWork);
}
commitHookLayoutEffectListMount(finishedWork);

if ((finishedWork.subtreeTag & PassiveSubtreeTag) !== NoSubtreeTag) {
schedulePassiveEffectCallback();
Expand Down Expand Up @@ -521,6 +544,16 @@ function commitLifeCycles(
} else {
instance.componentDidMount();
}

if (__DEV__) {
if (enableDoubleInvokingEffects) {
// if there is no unmount function we don't have to double invoke
if (typeof instance.componentWillUnmount === 'function') {
safelyCallComponentWillUnmount(finishedWork, instance);
}
instance.componentDidMount();
}
}
} else {
const prevProps =
finishedWork.elementType === finishedWork.type
Expand Down Expand Up @@ -1428,23 +1461,7 @@ function commitWork(current: Fiber | null, finishedWork: Fiber): void {
// This prevents sibling component effects from interfering with each other,
// e.g. a destroy function in one component should never override a ref set
// by a create function in another component during the same commit.
if (
enableProfilerTimer &&
enableProfilerCommitHooks &&
finishedWork.mode & ProfileMode
) {
try {
startLayoutEffectTimer();
commitHookEffectListUnmount(
HookLayout | HookHasEffect,
finishedWork,
);
} finally {
recordLayoutEffectDuration(finishedWork);
}
} else {
commitHookEffectListUnmount(HookLayout | HookHasEffect, finishedWork);
}
commitHookLayoutEffectListUnmount(finishedWork);
return;
}
case Profiler: {
Expand Down Expand Up @@ -1491,20 +1508,7 @@ function commitWork(current: Fiber | null, finishedWork: Fiber): void {
// This prevents sibling component effects from interfering with each other,
// e.g. a destroy function in one component should never override a ref set
// by a create function in another component during the same commit.
if (
enableProfilerTimer &&
enableProfilerCommitHooks &&
finishedWork.mode & ProfileMode
) {
try {
startLayoutEffectTimer();
commitHookEffectListUnmount(HookLayout | HookHasEffect, finishedWork);
} finally {
recordLayoutEffectDuration(finishedWork);
}
} else {
commitHookEffectListUnmount(HookLayout | HookHasEffect, finishedWork);
}
commitHookLayoutEffectListUnmount(finishedWork);
return;
}
case ClassComponent: {
Expand Down
104 changes: 54 additions & 50 deletions packages/react-reconciler/src/ReactFiberCommitWork.old.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import {
enableFundamentalAPI,
enableSuspenseCallback,
enableScopeAPI,
enableDoubleInvokingEffects,
} from 'shared/ReactFeatureFlags';
import {
FunctionComponent,
Expand Down Expand Up @@ -311,7 +312,8 @@ function commitBeforeMutationLifeCycles(
);
}

function commitHookEffectListUnmount(tag: number, finishedWork: Fiber) {
function commitHookLayoutEffectListUnmount(finishedWork: Fiber) {
const tag = HookLayout | HookHasEffect;
const updateQueue: FunctionComponentUpdateQueue | null = (finishedWork.updateQueue: any);
const lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
if (lastEffect !== null) {
Expand All @@ -323,15 +325,29 @@ function commitHookEffectListUnmount(tag: number, finishedWork: Fiber) {
const destroy = effect.destroy;
effect.destroy = undefined;
if (destroy !== undefined) {
destroy();
if (
enableProfilerTimer &&
enableProfilerCommitHooks &&
finishedWork.mode & ProfileMode
) {
try {
startLayoutEffectTimer();
destroy();
} finally {
recordLayoutEffectDuration(finishedWork);
}
} else {
destroy();
}
}
}
effect = effect.next;
} while (effect !== firstEffect);
}
}

function commitHookEffectListMount(tag: number, finishedWork: Fiber) {
function commitHookLayoutEffectListMount(finishedWork: Fiber) {
const tag = HookLayout | HookHasEffect;
const updateQueue: FunctionComponentUpdateQueue | null = (finishedWork.updateQueue: any);
const lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
if (lastEffect !== null) {
Expand All @@ -341,8 +357,20 @@ function commitHookEffectListMount(tag: number, finishedWork: Fiber) {
if ((effect.tag & tag) === tag) {
// Mount
const create = effect.create;
effect.destroy = create();

if (
enableProfilerTimer &&
enableProfilerCommitHooks &&
finishedWork.mode & ProfileMode
) {
try {
startLayoutEffectTimer();
effect.destroy = create();
} finally {
recordLayoutEffectDuration(finishedWork);
}
} else {
effect.destroy = create();
}
if (__DEV__) {
const destroy = effect.destroy;
if (destroy !== undefined && typeof destroy !== 'function') {
Expand Down Expand Up @@ -374,6 +402,14 @@ function commitHookEffectListMount(tag: number, finishedWork: Fiber) {
addendum,
);
}

if (enableDoubleInvokingEffects) {
effect.destroy = undefined;
if (typeof destroy === 'function') {
destroy();
}
effect.destroy = create();
}
}
}
effect = effect.next;
Expand Down Expand Up @@ -471,20 +507,7 @@ function commitLifeCycles(
// This is done to prevent sibling component effects from interfering with each other,
// e.g. a destroy function in one component should never override a ref set
// by a create function in another component during the same commit.
if (
enableProfilerTimer &&
enableProfilerCommitHooks &&
finishedWork.mode & ProfileMode
) {
try {
startLayoutEffectTimer();
commitHookEffectListMount(HookLayout | HookHasEffect, finishedWork);
} finally {
recordLayoutEffectDuration(finishedWork);
}
} else {
commitHookEffectListMount(HookLayout | HookHasEffect, finishedWork);
}
commitHookLayoutEffectListMount(finishedWork);

schedulePassiveEffects(finishedWork);
return;
Expand Down Expand Up @@ -537,6 +560,16 @@ function commitLifeCycles(
} else {
instance.componentDidMount();
}

if (__DEV__) {
if (enableDoubleInvokingEffects) {
// if there is no unmount function we don't have to double invoke
if (typeof instance.componentWillUnmount === 'function') {
safelyCallComponentWillUnmount(finishedWork, instance);
}
instance.componentDidMount();
}
}
} else {
const prevProps =
finishedWork.elementType === finishedWork.type
Expand Down Expand Up @@ -1451,23 +1484,7 @@ function commitWork(current: Fiber | null, finishedWork: Fiber): void {
// This prevents sibling component effects from interfering with each other,
// e.g. a destroy function in one component should never override a ref set
// by a create function in another component during the same commit.
if (
enableProfilerTimer &&
enableProfilerCommitHooks &&
finishedWork.mode & ProfileMode
) {
try {
startLayoutEffectTimer();
commitHookEffectListUnmount(
HookLayout | HookHasEffect,
finishedWork,
);
} finally {
recordLayoutEffectDuration(finishedWork);
}
} else {
commitHookEffectListUnmount(HookLayout | HookHasEffect, finishedWork);
}
commitHookLayoutEffectListUnmount(finishedWork);
return;
}
case Profiler: {
Expand Down Expand Up @@ -1514,20 +1531,7 @@ function commitWork(current: Fiber | null, finishedWork: Fiber): void {
// This prevents sibling component effects from interfering with each other,
// e.g. a destroy function in one component should never override a ref set
// by a create function in another component during the same commit.
if (
enableProfilerTimer &&
enableProfilerCommitHooks &&
finishedWork.mode & ProfileMode
) {
try {
startLayoutEffectTimer();
commitHookEffectListUnmount(HookLayout | HookHasEffect, finishedWork);
} finally {
recordLayoutEffectDuration(finishedWork);
}
} else {
commitHookEffectListUnmount(HookLayout | HookHasEffect, finishedWork);
}
commitHookLayoutEffectListUnmount(finishedWork);
return;
}
case ClassComponent: {
Expand Down
21 changes: 21 additions & 0 deletions packages/react-reconciler/src/ReactFiberWorkLoop.new.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import {
enableDebugTracing,
enableSchedulingProfiler,
enableScopeAPI,
enableDoubleInvokingEffects,
} from 'shared/ReactFeatureFlags';
import ReactSharedInternals from 'shared/ReactSharedInternals';
import invariant from 'shared/invariant';
Expand Down Expand Up @@ -2686,6 +2687,16 @@ function invokePassiveEffectCreate(effect: HookEffect): void {
effect.destroy = create();
}

function doubleInvokePassiveEffect(effect: HookEffect): void {
const create = effect.create;
const destroy = effect.destroy;
effect.destroy = undefined;
if (typeof destroy === 'function') {
destroy();
}
effect.destroy = create();
}

function flushPassiveMountEffects(firstChild: Fiber): void {
let fiber = firstChild;
while (fiber !== null) {
Expand Down Expand Up @@ -2747,6 +2758,16 @@ function flushPassiveMountEffectsImpl(fiber: Fiber): void {
effect,
);
}

if (enableDoubleInvokingEffects) {
invokeGuardedCallback(
null,
doubleInvokePassiveEffect,
null,
effect,
);
}

if (hasCaughtError()) {
invariant(fiber !== null, 'Should be working on an effect.');
const error = clearCaughtError();
Expand Down
Loading

0 comments on commit c927a2c

Please sign in to comment.