Skip to content

Commit 0bdb920

Browse files
authored
[Fizz] If we haven't painted yet, wait to reveal everything until next paint (#34230)
Before the first rAF, we don't know if there has been other paints before this and if so when. (We could get from performance observer.) We can assume that it's not earlier than 0 so we used delay up until the throttle time starting from zero but if the first paint is about to happen that can be very soon after. Instead, this reveals it during the next paint which should let us be able to get into the first paint. If we can trust `rel="expect"` to have done its thing we should schedule our raf before first paint but ofc browsers can cheat and paint earlier if they want to. If we're wrong, this is at least more batched than doing it synchronously. However it will mean that things might get more flashy than it should be if it would've been throttled. An alternative would be to always throttle first reveal.
1 parent f508edc commit 0bdb920

File tree

4 files changed

+21
-21
lines changed

4 files changed

+21
-21
lines changed

fixtures/ssr/src/components/LargeContent.js

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,4 @@
1-
import React, {
2-
Fragment,
3-
Suspense,
4-
unstable_SuspenseList as SuspenseList,
5-
} from 'react';
1+
import React, {Suspense, unstable_SuspenseList as SuspenseList} from 'react';
62

73
export default function LargeContent() {
84
return (

packages/react-dom-bindings/src/server/fizz-instruction-set/ReactDOMFizzInstructionSetInlineCodeStrings.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/react-dom-bindings/src/server/fizz-instruction-set/ReactDOMFizzInstructionSetShared.js

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -420,21 +420,24 @@ export function completeBoundary(suspenseBoundaryID, contentID) {
420420
if (window['$RB'].length === 2) {
421421
// This is the first time we've pushed to the batch. We need to schedule a callback
422422
// to flush the batch. This is delayed by the throttle heuristic.
423-
const globalMostRecentFallbackTime =
424-
typeof window['$RT'] !== 'number' ? 0 : window['$RT'];
425-
const currentTime = performance.now();
426-
const msUntilTimeout =
427-
// If the throttle would make us miss the target metric, then shorten the throttle.
428-
// performance.now()'s zero value is assumed to be the start time of the metric.
429-
currentTime < TARGET_VANITY_METRIC &&
430-
currentTime > TARGET_VANITY_METRIC - FALLBACK_THROTTLE_MS
431-
? TARGET_VANITY_METRIC - currentTime
432-
: // Otherwise it's throttled starting from last commit time.
433-
globalMostRecentFallbackTime + FALLBACK_THROTTLE_MS - currentTime;
434-
// We always schedule the flush in a timer even if it's very low or negative to allow
435-
// for multiple completeBoundary calls that are already queued to have a chance to
436-
// make the batch.
437-
setTimeout(window['$RV'].bind(null, window['$RB']), msUntilTimeout);
423+
if (typeof window['$RT'] !== 'number') {
424+
// If we haven't had our rAF callback yet, schedule everything for the first paint.
425+
requestAnimationFrame(window['$RV'].bind(null, window['$RB']));
426+
} else {
427+
const currentTime = performance.now();
428+
const msUntilTimeout =
429+
// If the throttle would make us miss the target metric, then shorten the throttle.
430+
// performance.now()'s zero value is assumed to be the start time of the metric.
431+
currentTime < TARGET_VANITY_METRIC &&
432+
currentTime > TARGET_VANITY_METRIC - FALLBACK_THROTTLE_MS
433+
? TARGET_VANITY_METRIC - currentTime
434+
: // Otherwise it's throttled starting from last commit time.
435+
window['$RT'] + FALLBACK_THROTTLE_MS - currentTime;
436+
// We always schedule the flush in a timer even if it's very low or negative to allow
437+
// for multiple completeBoundary calls that are already queued to have a chance to
438+
// make the batch.
439+
setTimeout(window['$RV'].bind(null, window['$RB']), msUntilTimeout);
440+
}
438441
}
439442
}
440443

packages/react-dom/src/__tests__/ReactDOMFizzStaticBrowser-test.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ describe('ReactDOMFizzStaticBrowser', () => {
4040

4141
// We need the mocked version of setTimeout inside the document.
4242
window.setTimeout = setTimeout;
43+
window.requestAnimationFrame = setTimeout;
4344

4445
patchMessageChannel();
4546
serverAct = require('internal-test-utils').serverAct;

0 commit comments

Comments
 (0)