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 13, 2019
1 parent cc24d0e commit 16dbe84
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 8 deletions.
10 changes: 2 additions & 8 deletions packages/react-reconciler/src/ReactFiberBeginWork.js
Expand Up @@ -83,13 +83,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 @@ -974,7 +968,7 @@ function updateHostComponent(current, workInProgress, renderExpirationTime) {
// Check the host config to see if the children are offscreen/hidden.
if (
renderExpirationTime !== Never &&
workInProgress.mode & ConcurrentMode &&
workInProgress.mode & BatchedMode &&
shouldDeprioritizeSubtree(type, nextProps)
) {
// Schedule this fiber to re-render at offscreen priority. Then bailout.
Expand Down
5 changes: 5 additions & 0 deletions packages/react-reconciler/src/ReactFiberScheduler.js
Expand Up @@ -62,6 +62,7 @@ import {
BatchedMode,
ConcurrentMode,
} from './ReactTypeOfMode';
import {ConcurrentRoot} from 'shared/ReactRootTags';
import {
HostRoot,
ClassComponent,
Expand Down Expand Up @@ -728,6 +729,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
Expand Up @@ -163,4 +163,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 16dbe84

Please sign in to comment.