Skip to content

Commit

Permalink
Support hidden deprioritization in Batched Mode
Browse files Browse the repository at this point in the history
Hidden trees will tear and commit in a separate render, as in Concurrent
Mode. Unlike Concurrent Mode, once the hidden tree begins, it will
finish without yielding.
  • Loading branch information
acdlite committed May 23, 2019
1 parent 025b07b commit 17921f7
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 9 deletions.
12 changes: 3 additions & 9 deletions packages/react-reconciler/src/ReactFiberBeginWork.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,13 +84,7 @@ import {
Never,
computeAsyncExpiration,
} from './ReactFiberExpirationTime';
import {
ConcurrentMode,
NoMode,
ProfileMode,
StrictMode,
BatchedMode,
} from './ReactTypeOfMode';
import {NoMode, ProfileMode, StrictMode, BatchedMode} from './ReactTypeOfMode';
import {
shouldSetTextContent,
shouldDeprioritizeSubtree,
Expand Down Expand Up @@ -980,7 +974,7 @@ function updateHostComponent(current, workInProgress, renderExpirationTime) {

// Check the host config to see if the children are offscreen/hidden.
if (
workInProgress.mode & ConcurrentMode &&
workInProgress.mode & BatchedMode &&
renderExpirationTime !== Never &&
shouldDeprioritizeSubtree(type, nextProps)
) {
Expand Down Expand Up @@ -2257,7 +2251,7 @@ function beginWork(
case HostComponent:
pushHostContext(workInProgress);
if (
workInProgress.mode & ConcurrentMode &&
workInProgress.mode & BatchedMode &&
renderExpirationTime !== Never &&
shouldDeprioritizeSubtree(workInProgress.type, newProps)
) {
Expand Down
5 changes: 5 additions & 0 deletions packages/react-reconciler/src/ReactFiberScheduler.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ import {
BatchedMode,
ConcurrentMode,
} from './ReactTypeOfMode';
import {ConcurrentRoot} from 'shared/ReactRootTags';
import {
HostRoot,
ClassComponent,
Expand Down Expand Up @@ -776,6 +777,10 @@ function renderRoot(
'Should not already be working.',
);

if (root.tag !== ConcurrentRoot) {
isSync = true;
}

if (enableUserTimingAPI && expirationTime !== Sync) {
const didExpire = isSync;
stopRequestCallbackTimer(didExpire);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -161,4 +161,46 @@ describe('ReactBatchedMode', () => {
expect(Scheduler).toFlushExpired(['A1']);
expect(root).toMatchRenderedOutput('A1B1');
});

it('hidden subtrees are deprioritized but not yieldy', () => {
const {useEffect} = React;

const root = ReactNoop.createSyncRoot();
function App() {
useEffect(() => Scheduler.yieldValue('Commit'));
return (
<Suspense fallback={<Text text="Loading..." />}>
<div hidden={true}>
<Text text="A" />
<Text text="B" />
<Text text="C" />
</div>
<div>
<Text text="D" />
<Text text="E" />
<Text text="F" />
</div>
</Suspense>
);
}

root.render(<App />);
expect(Scheduler).toFlushAndYieldThrough(['D', 'E', 'F', 'Commit']);
expect(root).toMatchRenderedOutput(
<React.Fragment>
<div hidden={true} />
<div>DEF</div>
</React.Fragment>,
);

Scheduler.unstable_flushNumberOfYields(1);
expect(Scheduler).toHaveYielded(['A', 'B', 'C']);
Scheduler.flushAll();
expect(root).toMatchRenderedOutput(
<React.Fragment>
<div hidden={true}>ABC</div>
<div>DEF</div>
</React.Fragment>,
);
});
});

0 comments on commit 17921f7

Please sign in to comment.