From 50887a915243256a880136382fc9e8d370d8cbee Mon Sep 17 00:00:00 2001 From: Aurora Scharff Date: Thu, 9 Jul 2026 15:43:01 +0200 Subject: [PATCH 01/11] Tune Suspense demo heights, data delay, and DOM comparison wording --- src/content/reference/react/Suspense.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/content/reference/react/Suspense.md b/src/content/reference/react/Suspense.md index 1b6cf37ec13..36da3138eec 100644 --- a/src/content/reference/react/Suspense.md +++ b/src/content/reference/react/Suspense.md @@ -2978,7 +2978,7 @@ export function freshImageUrl() { ```css #root { - min-height: 440px; + min-height: 320px; } .card { margin-top: 1em; @@ -3025,7 +3025,7 @@ hr { All of these waits work together. In the example below, the `ProfileCard` component suspends while its data loads, and renders a stylesheet with `precedence`, text in a new font, and a portrait. React keeps the skeleton visible while the data and the stylesheet load. The `` reveal then waits for the font and the image, so the card appears complete. -For comparison, the plain DOM version loads the same data and shows every resource arriving on its own schedule: +For comparison, the second button performs the same update with plain DOM, without React. It loads the same data first, and then each resource pops in as it arrives: @@ -3155,7 +3155,7 @@ export function freshImageUrl() { export async function fetchQuote() { // Add a fake delay to make waiting noticeable. await new Promise((resolve) => { - setTimeout(resolve, 2000); + setTimeout(resolve, 300); }); return 'The best way to predict the future is to invent it.'; } From 049bd8e473f3009733dfd1c4ab43e5acc9d1c904 Mon Sep 17 00:00:00 2001 From: Aurora Scharff Date: Thu, 9 Jul 2026 15:47:04 +0200 Subject: [PATCH 02/11] Make section openers stand alone and restore demo timing --- src/content/reference/react/Suspense.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/content/reference/react/Suspense.md b/src/content/reference/react/Suspense.md index 36da3138eec..ff61654eb14 100644 --- a/src/content/reference/react/Suspense.md +++ b/src/content/reference/react/Suspense.md @@ -2740,7 +2740,7 @@ Where you place the `` relative to the boundary determines wheth ### Waiting for a font to load {/*waiting-for-a-font-to-load*/} -When a [``](/reference/react/ViewTransition) animates a Suspense boundary's reveal, React also waits for new fonts the content introduces, up to a timeout, so the text doesn't flash with a fallback font. This only happens during a `` update. +When a [``](/reference/react/ViewTransition) animates a Suspense boundary's reveal, React waits for new fonts the content introduces, up to a timeout, so the text doesn't flash with a fallback font. This only happens during a `` update. In the example below, the Suspense boundary is wrapped in a ``, and the `Quote` component suspends while its data loads. Rendering the quote starts its font download. React keeps the fallback visible until the font has loaded, so the quote appears already in its font. @@ -2890,7 +2890,7 @@ hr { ### Waiting for an image to load {/*waiting-for-an-image-to-load*/} -Images work the same way: when a [``](/reference/react/ViewTransition) animates a Suspense boundary's reveal, React waits for visible images to load, up to a timeout, so the animation doesn't start with a half-loaded image. This only happens during a `` update. Adding an `onLoad` handler opts a specific image out, even inside a ``. +When a [``](/reference/react/ViewTransition) animates a Suspense boundary's reveal, React waits for visible images to load, up to a timeout, so the animation doesn't start with a half-loaded image. This only happens during a `` update. Adding an `onLoad` handler opts a specific image out, even inside a ``. In the example below, the Suspense boundary is wrapped in a `` and shows a profile skeleton until the portrait has loaded. @@ -3023,9 +3023,9 @@ hr { ### Coordinating fonts, images, and stylesheets {/*coordinating-fonts-images-and-stylesheets*/} -All of these waits work together. In the example below, the `ProfileCard` component suspends while its data loads, and renders a stylesheet with `precedence`, text in a new font, and a portrait. React keeps the skeleton visible while the data and the stylesheet load. The `` reveal then waits for the font and the image, so the card appears complete. +A single Suspense boundary can wait for several of these resources at once. In the example below, the `ProfileCard` component suspends while its data loads, and renders a stylesheet with `precedence`, text in a new font, and a portrait. React keeps the skeleton visible while the data and the stylesheet load. The `` reveal then waits for the font and the image, so the card appears complete. -For comparison, the second button performs the same update with plain DOM, without React. It loads the same data first, and then each resource pops in as it arrives: +For comparison, the plain DOM version loads the same data and shows every resource arriving on its own schedule: @@ -3155,7 +3155,7 @@ export function freshImageUrl() { export async function fetchQuote() { // Add a fake delay to make waiting noticeable. await new Promise((resolve) => { - setTimeout(resolve, 300); + setTimeout(resolve, 2000); }); return 'The best way to predict the future is to invent it.'; } From e230b6328c3c710d1062d09c3b3fa79eb7301290 Mon Sep 17 00:00:00 2001 From: Aurora Scharff Date: Thu, 9 Jul 2026 15:48:15 +0200 Subject: [PATCH 03/11] Shrink image demo portraits so both cards fit without layout shift --- src/content/reference/react/Suspense.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/content/reference/react/Suspense.md b/src/content/reference/react/Suspense.md index ff61654eb14..81c95f1cfc4 100644 --- a/src/content/reference/react/Suspense.md +++ b/src/content/reference/react/Suspense.md @@ -2906,7 +2906,7 @@ import VanillaProfile from './VanillaProfile.js'; function Profile({ src }) { return (
- Jack Pope + Jack Pope

Jack Pope

); @@ -2955,7 +2955,7 @@ export default function VanillaProfile() { const ref = useRef(null); function show() { ref.current.innerHTML = `
- Jack Pope + Jack Pope

Jack Pope

`; } @@ -2978,7 +2978,7 @@ export function freshImageUrl() { ```css #root { - min-height: 320px; + min-height: 390px; } .card { margin-top: 1em; @@ -2992,8 +2992,8 @@ export function freshImageUrl() { font-weight: bold; } .avatar-placeholder { - width: 100px; - height: 100px; + width: 80px; + height: 80px; border-radius: 50%; background: #dfe3e9; } From 3611f1d84aef74d78ff7f80ccb362ba8e5af9cb9 Mon Sep 17 00:00:00 2001 From: Aurora Scharff Date: Thu, 9 Jul 2026 15:50:13 +0200 Subject: [PATCH 04/11] Name the resources in the combined section opener --- src/content/reference/react/Suspense.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/reference/react/Suspense.md b/src/content/reference/react/Suspense.md index 81c95f1cfc4..2cbfc065d72 100644 --- a/src/content/reference/react/Suspense.md +++ b/src/content/reference/react/Suspense.md @@ -3023,7 +3023,7 @@ hr { ### Coordinating fonts, images, and stylesheets {/*coordinating-fonts-images-and-stylesheets*/} -A single Suspense boundary can wait for several of these resources at once. In the example below, the `ProfileCard` component suspends while its data loads, and renders a stylesheet with `precedence`, text in a new font, and a portrait. React keeps the skeleton visible while the data and the stylesheet load. The `` reveal then waits for the font and the image, so the card appears complete. +A single Suspense boundary can wait for data, stylesheets, fonts, and images at once. In the example below, the `ProfileCard` component suspends while its data loads, and renders a stylesheet with `precedence`, text in a new font, and a portrait. React keeps the skeleton visible while the data and the stylesheet load. The `` reveal then waits for the font and the image, so the card appears complete. For comparison, the plain DOM version loads the same data and shows every resource arriving on its own schedule: From edb4084712033df9b7f541359c437abd4c7a327b Mon Sep 17 00:00:00 2001 From: Aurora Scharff Date: Thu, 9 Jul 2026 15:51:09 +0200 Subject: [PATCH 05/11] State the ViewTransition condition in the combined section opener --- src/content/reference/react/Suspense.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/reference/react/Suspense.md b/src/content/reference/react/Suspense.md index 2cbfc065d72..85aec6b010f 100644 --- a/src/content/reference/react/Suspense.md +++ b/src/content/reference/react/Suspense.md @@ -3023,7 +3023,7 @@ hr { ### Coordinating fonts, images, and stylesheets {/*coordinating-fonts-images-and-stylesheets*/} -A single Suspense boundary can wait for data, stylesheets, fonts, and images at once. In the example below, the `ProfileCard` component suspends while its data loads, and renders a stylesheet with `precedence`, text in a new font, and a portrait. React keeps the skeleton visible while the data and the stylesheet load. The `` reveal then waits for the font and the image, so the card appears complete. +When its reveal is animated by a [``](/reference/react/ViewTransition), a single Suspense boundary can wait for data, stylesheets, fonts, and images at once. In the example below, the `ProfileCard` component suspends while its data loads, and renders a stylesheet with `precedence`, text in a new font, and a portrait. React keeps the skeleton visible while the data and the stylesheet load. The `` reveal then waits for the font and the image, so the card appears complete. For comparison, the plain DOM version loads the same data and shows every resource arriving on its own schedule: From 75668445abb47fabe72a6be71f54b3cfcef1b942 Mon Sep 17 00:00:00 2001 From: Aurora Scharff Date: Thu, 9 Jul 2026 15:51:58 +0200 Subject: [PATCH 06/11] Align combined section opener with sibling sections --- src/content/reference/react/Suspense.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/reference/react/Suspense.md b/src/content/reference/react/Suspense.md index 85aec6b010f..28189a66ed7 100644 --- a/src/content/reference/react/Suspense.md +++ b/src/content/reference/react/Suspense.md @@ -3023,7 +3023,7 @@ hr { ### Coordinating fonts, images, and stylesheets {/*coordinating-fonts-images-and-stylesheets*/} -When its reveal is animated by a [``](/reference/react/ViewTransition), a single Suspense boundary can wait for data, stylesheets, fonts, and images at once. In the example below, the `ProfileCard` component suspends while its data loads, and renders a stylesheet with `precedence`, text in a new font, and a portrait. React keeps the skeleton visible while the data and the stylesheet load. The `` reveal then waits for the font and the image, so the card appears complete. +When a [``](/reference/react/ViewTransition) animates a Suspense boundary's reveal, React can wait for data, stylesheets, fonts, and images at once. In the example below, the `ProfileCard` component suspends while its data loads, and renders a stylesheet with `precedence`, text in a new font, and a portrait. React keeps the skeleton visible while the data and the stylesheet load. The `` reveal then waits for the font and the image, so the card appears complete. For comparison, the plain DOM version loads the same data and shows every resource arriving on its own schedule: From bcd97dfc044ccbff2993c2444e3d5059cb52f0ee Mon Sep 17 00:00:00 2001 From: Aurora Scharff Date: Thu, 9 Jul 2026 15:53:49 +0200 Subject: [PATCH 07/11] Frame font and image waiting as Suspense behavior gated on ViewTransition --- src/content/reference/react/Suspense.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/reference/react/Suspense.md b/src/content/reference/react/Suspense.md index 28189a66ed7..a30bf121ea1 100644 --- a/src/content/reference/react/Suspense.md +++ b/src/content/reference/react/Suspense.md @@ -3023,7 +3023,7 @@ hr { ### Coordinating fonts, images, and stylesheets {/*coordinating-fonts-images-and-stylesheets*/} -When a [``](/reference/react/ViewTransition) animates a Suspense boundary's reveal, React can wait for data, stylesheets, fonts, and images at once. In the example below, the `ProfileCard` component suspends while its data loads, and renders a stylesheet with `precedence`, text in a new font, and a portrait. React keeps the skeleton visible while the data and the stylesheet load. The `` reveal then waits for the font and the image, so the card appears complete. +A Suspense boundary waits for data and stylesheets on its own. When a [``](/reference/react/ViewTransition) animates its reveal, React also waits for fonts and images, so everything appears at once. In the example below, the `ProfileCard` component suspends while its data loads, and renders a stylesheet with `precedence`, text in a new font, and a portrait. React keeps the skeleton visible while the data and the stylesheet load. The `` reveal then waits for the font and the image, so the card appears complete. For comparison, the plain DOM version loads the same data and shows every resource arriving on its own schedule: From 36e7a698fdb1ad247b987929fc736c022cd44085 Mon Sep 17 00:00:00 2001 From: Aurora Scharff Date: Thu, 9 Jul 2026 15:56:32 +0200 Subject: [PATCH 08/11] Match the combined section opener to its sibling sections --- src/content/reference/react/Suspense.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/reference/react/Suspense.md b/src/content/reference/react/Suspense.md index a30bf121ea1..e8f8ca71879 100644 --- a/src/content/reference/react/Suspense.md +++ b/src/content/reference/react/Suspense.md @@ -3023,7 +3023,7 @@ hr { ### Coordinating fonts, images, and stylesheets {/*coordinating-fonts-images-and-stylesheets*/} -A Suspense boundary waits for data and stylesheets on its own. When a [``](/reference/react/ViewTransition) animates its reveal, React also waits for fonts and images, so everything appears at once. In the example below, the `ProfileCard` component suspends while its data loads, and renders a stylesheet with `precedence`, text in a new font, and a portrait. React keeps the skeleton visible while the data and the stylesheet load. The `` reveal then waits for the font and the image, so the card appears complete. +A Suspense boundary can wait for data, stylesheets, fonts, and images at once. Waiting for fonts and images only happens during a [``](/reference/react/ViewTransition) update. In the example below, the `ProfileCard` component suspends while its data loads, and renders a stylesheet with `precedence`, text in a new font, and a portrait. React keeps the skeleton visible while the data and the stylesheet load. The `` reveal then waits for the font and the image, so the card appears complete. For comparison, the plain DOM version loads the same data and shows every resource arriving on its own schedule: From 7380041778207c48fd6090dec17d2f11f70413a7 Mon Sep 17 00:00:00 2001 From: Aurora Scharff Date: Thu, 9 Jul 2026 15:58:32 +0200 Subject: [PATCH 09/11] Document the experimental defer prop --- src/content/reference/react/Suspense.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/content/reference/react/Suspense.md b/src/content/reference/react/Suspense.md index e8f8ca71879..dfaad7ab61f 100644 --- a/src/content/reference/react/Suspense.md +++ b/src/content/reference/react/Suspense.md @@ -26,6 +26,7 @@ title: #### Props {/*props*/} * `children`: The actual UI you intend to render. If `children` suspends while rendering, the Suspense boundary will switch to rendering `fallback`. * `fallback`: An alternate UI to render in place of the actual UI if it has not finished loading. Any valid React node is accepted, though in practice, a fallback is a lightweight placeholder view, such as a loading spinner or skeleton. Suspense will automatically switch to `fallback` when `children` suspends, and back to `children` when the data is ready. If `fallback` suspends while rendering, it will activate the closest parent Suspense boundary. +* **optional** `defer`: A boolean. When `true`, React may show the `fallback` first and render or stream `children` later, even when nothing in them suspends. Use it for content that is expensive to render. Defaults to `false`. #### Caveats {/*caveats*/} @@ -48,7 +49,7 @@ A Suspense boundary waits for its content to be ready before revealing it. Any o - Waiting for a large boundary's HTML to arrive during streaming server rendering. Sending HTML takes time, so a boundary with enough content activates even when nothing in it suspends. React reveals the content as the HTML arrives. - Loading fonts. Suspense doesn't wait for fonts by default, but a [``](/reference/react/ViewTransition) update waits for new fonts to load, up to a timeout, so text doesn't flash with a fallback font. [See an example below.](#waiting-for-a-font-to-load) - Loading images. Suspense doesn't wait for images by default, but during a [``](/reference/react/ViewTransition) update, React blocks the boundary until the image loads, up to a timeout. Adding an `onLoad` handler opts a specific image out. [See an example below.](#waiting-for-an-image-to-load) -- Performing CPU-bound render work inside a `` boundary marked with the `defer` prop. +- Performing CPU-bound render work inside a [``](#props) boundary. From 9198dbc1d6c623969d46f94e74ec5b5105223d0d Mon Sep 17 00:00:00 2001 From: Aurora Scharff Date: Thu, 9 Jul 2026 16:20:02 +0200 Subject: [PATCH 10/11] Reduce the combined example's data delay --- src/content/reference/react/Suspense.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/reference/react/Suspense.md b/src/content/reference/react/Suspense.md index dfaad7ab61f..f95d0bcdb6b 100644 --- a/src/content/reference/react/Suspense.md +++ b/src/content/reference/react/Suspense.md @@ -3156,7 +3156,7 @@ export function freshImageUrl() { export async function fetchQuote() { // Add a fake delay to make waiting noticeable. await new Promise((resolve) => { - setTimeout(resolve, 2000); + setTimeout(resolve, 1000); }); return 'The best way to predict the future is to invent it.'; } From c1839d6dd6b9cccdb2ebd4155a1db92df2f0162b Mon Sep 17 00:00:00 2001 From: Aurora Scharff Date: Thu, 9 Jul 2026 16:47:20 +0200 Subject: [PATCH 11/11] tweak --- src/content/reference/react/Suspense.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/content/reference/react/Suspense.md b/src/content/reference/react/Suspense.md index f95d0bcdb6b..8051ca01f16 100644 --- a/src/content/reference/react/Suspense.md +++ b/src/content/reference/react/Suspense.md @@ -2380,7 +2380,7 @@ A stylesheet rendered with [`` and a `precedence` prop](/ In the example below, the `Card` component renders a stylesheet with `precedence`. Press "Show card": React shows the fallback until the stylesheet has loaded, and then reveals the card with its styles applied. -For comparison, the second button performs the same update with plain DOM in a separate document, without React. Nothing waits for the stylesheet, so the card's text appears in a fallback font first and then switches: +For comparison, the second button performs the same update without React, in a separate document. Nothing waits for the stylesheet, so the card's text appears in a fallback font first and then switches: @@ -2450,7 +2450,7 @@ export default function VanillaCard() { } return ( <> - +