Skip to content

Commit

Permalink
explore force scheduling work to help with react fresh cases
Browse files Browse the repository at this point in the history
  • Loading branch information
gnoff committed May 5, 2020
1 parent c8a5937 commit c1c0529
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 9 deletions.
26 changes: 25 additions & 1 deletion packages/react-reconciler/src/ReactFiberBeginWork.js
Original file line number Diff line number Diff line change
Expand Up @@ -2792,6 +2792,7 @@ export function markWorkInProgressReceivedUpdate() {
}

function reifyNextWork(workInProgress: Fiber, renderExpirationTime) {
// console.log('reifying next work from ', workInProgress.tag);
let fiber = workInProgress.child;
if (fiber !== null) {
// Set the return pointer of the child to the work-in-progress fiber.
Expand All @@ -2802,11 +2803,32 @@ function reifyNextWork(workInProgress: Fiber, renderExpirationTime) {
let nextFiber;

if (fiber.mode & ReifiedWorkMode) {
// this fiber and it's sub tree have already been reified. whatever work exists
// there we need to progress forward with it. no need to delve deeper
nextFiber = null;
} else {
fiber.mode |= ReifiedWorkMode;

if (fiber.expirationTime >= renderExpirationTime) {
// console.log(
// '-- checking',
// fiber.tag,
// fiber._debugNeedsRemount,
// fiber.type && fiber.type.name,
// );
// fiber.alternate &&
// console.log(
// '-- checking alternate',
// fiber.alternate.tag,
// fiber.alternate._debugNeedsRemount,
// fiber.type === fiber.alternate.type,
// );

if (__DEV__ && fiber._debugNeedsRemount) {
// this fiber needs to be remounted. we can bail out of the reify algo for this
// subtree and let normal work takes it's course
console.log('fiber', fiber.tag, 'has debug marker');
nextFiber = null;
} else if (fiber.expirationTime >= renderExpirationTime) {
let didBailout;
switch (fiber.tag) {
case ForwardRef:
Expand Down Expand Up @@ -3023,6 +3045,8 @@ function beginWork(
): Fiber | null {
const updateExpirationTime = workInProgress.expirationTime;

// console.log('beginWork', workInProgress.tag);

if (__DEV__) {
if (workInProgress._debugNeedsRemount && current !== null) {
// This will restart the begin phase with a new fiber.
Expand Down
2 changes: 1 addition & 1 deletion packages/react-reconciler/src/ReactFiberHotReloading.js
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,7 @@ function scheduleFibersWithFamiliesRecursively(
fiber._debugNeedsRemount = true;
}
if (needsRemount || needsRender) {
scheduleWork(fiber, Sync);
scheduleWork(fiber, Sync, true);
}
if (child !== null && !needsRemount) {
scheduleFibersWithFamiliesRecursively(
Expand Down
45 changes: 38 additions & 7 deletions packages/react-reconciler/src/ReactFiberWorkLoop.js
Original file line number Diff line number Diff line change
Expand Up @@ -380,11 +380,12 @@ export function computeExpirationForFiber(
export function scheduleUpdateOnFiber(
fiber: Fiber,
expirationTime: ExpirationTime,
force?: boolean,
) {
checkForNestedUpdates();
warnAboutInvalidUpdatesOnClassComponentsInDEV(fiber);

const root = markUpdateTimeFromFiberToRoot(fiber, expirationTime);
const root = markUpdateTimeFromFiberToRoot(fiber, expirationTime, force);
if (root === null) {
warnAboutUpdateOnUnmountedFiberInDEV(fiber);
return;
Expand Down Expand Up @@ -453,19 +454,31 @@ export const scheduleWork = scheduleUpdateOnFiber;
// work without treating it as a typical update that originates from an event;
// e.g. retrying a Suspense boundary isn't an update, but it does schedule work
// on a fiber.
function markUpdateTimeFromFiberToRoot(fiber, expirationTime) {
function markUpdateTimeFromFiberToRoot(fiber, expirationTime, force) {
// Update the source fiber's expiration time
if (fiber.expirationTime < expirationTime) {
fiber.expirationTime = expirationTime;
if (enableReifyNextWork) {
fiber.mode &= ~ReifiedWorkMode;
if (force === true) {
// console.log('marking path as reified');
fiber.mode |= ReifiedWorkMode;
} else {
// console.log('marking path as NOT reified');
fiber.mode &= ~ReifiedWorkMode;
}
}
}
let alternate = fiber.alternate;
if (alternate !== null && alternate.expirationTime < expirationTime) {
alternate.expirationTime = expirationTime;
if (enableReifyNextWork) {
alternate.mode &= ~ReifiedWorkMode;
if (force === true) {
// console.log('marking alternate path as reified');
alternate.mode |= ReifiedWorkMode;
} else {
// console.log('marking alternate path as NOT reified');
alternate.mode &= ~ReifiedWorkMode;
}
}
}
// Walk the parent path to the root and update the child expiration time.
Expand All @@ -479,15 +492,27 @@ function markUpdateTimeFromFiberToRoot(fiber, expirationTime) {
if (node.childExpirationTime < expirationTime) {
node.childExpirationTime = expirationTime;
if (enableReifyNextWork) {
node.mode &= ~ReifiedWorkMode;
if (force === true) {
// console.log('marking path as reified');
node.mode |= ReifiedWorkMode;
} else {
// console.log('marking path as NOT reified');
node.mode &= ~ReifiedWorkMode;
}
}
if (
alternate !== null &&
alternate.childExpirationTime < expirationTime
) {
alternate.childExpirationTime = expirationTime;
if (enableReifyNextWork) {
alternate.mode &= ~ReifiedWorkMode;
if (force === true) {
// console.log('marking alternate path as reified');
alternate.mode |= ReifiedWorkMode;
} else {
// console.log('marking alternate path as NOT reified');
alternate.mode &= ~ReifiedWorkMode;
}
}
}
} else if (
Expand All @@ -496,7 +521,13 @@ function markUpdateTimeFromFiberToRoot(fiber, expirationTime) {
) {
alternate.childExpirationTime = expirationTime;
if (enableReifyNextWork) {
alternate.mode &= ~ReifiedWorkMode;
if (force === true) {
// console.log('marking alternate path as reified');
alternate.mode |= ReifiedWorkMode;
} else {
// console.log('marking alternate path as NOT reified');
alternate.mode &= ~ReifiedWorkMode;
}
}
}
if (node.return === null && node.tag === HostRoot) {
Expand Down
3 changes: 3 additions & 0 deletions packages/react-refresh/src/ReactFreshRuntime.js
Original file line number Diff line number Diff line change
Expand Up @@ -149,11 +149,14 @@ function isReactClass(type) {

function canPreserveStateBetween(prevType, nextType) {
if (isReactClass(prevType) || isReactClass(nextType)) {
console.log('this update CANNOT preserve state');
return false;
}
if (haveEqualSignatures(prevType, nextType)) {
console.log('this update CAN preserve state');
return true;
}
console.log('DEFAULT CASE this update CANNOT preserve state');
return false;
}

Expand Down

0 comments on commit c1c0529

Please sign in to comment.