Skip to content

Add fetchpriority=low to IMG tags in collapsed Details blocks#76269

Merged
westonruter merged 8 commits intotrunkfrom
fix/collapsed-details-img-fetchpriority
Mar 10, 2026
Merged

Add fetchpriority=low to IMG tags in collapsed Details blocks#76269
westonruter merged 8 commits intotrunkfrom
fix/collapsed-details-img-fetchpriority

Conversation

@westonruter
Copy link
Member

What?

Fixes #76268

Before ❌
<details class="wp-block-details">
  <summary>Collapsed kitty</summary>
  <figure class="wp-block-image size-large">
    <img
      fetchpriority="high"
      decoding="async"
      width="1024"
      height="771"
      sizes="(max-width: 645px) 100vw, 645px"
      src="http://localhost:8000/wp-content/uploads/2026/03/PXL_20260302_201050363-1024x771.jpg"
      alt=""
      class="wp-image-415"
      srcset="
        http://localhost:8000/wp-content/uploads/2026/03/PXL_20260302_201050363-1024x771.jpg  1024w,
        http://localhost:8000/wp-content/uploads/2026/03/PXL_20260302_201050363-300x226.jpg    300w,
        http://localhost:8000/wp-content/uploads/2026/03/PXL_20260302_201050363-768x578.jpg    768w,
        http://localhost:8000/wp-content/uploads/2026/03/PXL_20260302_201050363-1536x1157.jpg 1536w,
        http://localhost:8000/wp-content/uploads/2026/03/PXL_20260302_201050363-2048x1542.jpg 2048w
      "
    />
  </figure>
</details>

<details class="wp-block-details" open>
  <summary>Expanded bison</summary>
  <figure class="wp-block-image size-large">
    <img
      decoding="async"
      width="1024"
      height="683"
      sizes="(max-width: 645px) 100vw, 645px"
      src="http://localhost:8000/wp-content/uploads/2025/11/Bison_with_its_young-2560w-1024x683.jpg"
      alt=""
      class="wp-image-37"
      srcset="
        http://localhost:8000/wp-content/uploads/2025/11/Bison_with_its_young-2560w-1024x683.jpg  1024w,
        http://localhost:8000/wp-content/uploads/2025/11/Bison_with_its_young-2560w-300x200.jpg    300w,
        http://localhost:8000/wp-content/uploads/2025/11/Bison_with_its_young-2560w-768x512.jpg    768w,
        http://localhost:8000/wp-content/uploads/2025/11/Bison_with_its_young-2560w-1536x1025.jpg 1536w,
        http://localhost:8000/wp-content/uploads/2025/11/Bison_with_its_young-2560w-2048x1366.jpg 2048w
      "
    />
  </figure>
</details>
After ✅
<details
  class="wp-block-details is-layout-flow wp-block-details-is-layout-flow"
>
  <summary>Collapsed kitty</summary>
  <figure class="wp-block-image size-large">
    <img
      decoding="async"
      width="1024"
      height="771"
      fetchpriority="low"
      src="http://localhost:8000/wp-content/uploads/2026/03/PXL_20260302_201050363-1024x771.jpg"
      alt=""
      class="wp-image-415"
      srcset="
        http://localhost:8000/wp-content/uploads/2026/03/PXL_20260302_201050363-1024x771.jpg  1024w,
        http://localhost:8000/wp-content/uploads/2026/03/PXL_20260302_201050363-300x226.jpg    300w,
        http://localhost:8000/wp-content/uploads/2026/03/PXL_20260302_201050363-768x578.jpg    768w,
        http://localhost:8000/wp-content/uploads/2026/03/PXL_20260302_201050363-1536x1157.jpg 1536w,
        http://localhost:8000/wp-content/uploads/2026/03/PXL_20260302_201050363-2048x1542.jpg 2048w
      "
      sizes="(max-width: 1024px) 100vw, 1024px"
    />
  </figure>
</details>

<details
  class="wp-block-details is-layout-flow wp-block-details-is-layout-flow"
  open
>
  <summary>Expanded bison</summary>
  <figure class="wp-block-image size-large">
    <img
      fetchpriority="high"
      decoding="async"
      width="1024"
      height="683"
      src="http://localhost:8000/wp-content/uploads/2025/11/Bison_with_its_young-2560w-1024x683.jpg"
      alt=""
      class="wp-image-37"
      srcset="
        http://localhost:8000/wp-content/uploads/2025/11/Bison_with_its_young-2560w-1024x683.jpg  1024w,
        http://localhost:8000/wp-content/uploads/2025/11/Bison_with_its_young-2560w-300x200.jpg    300w,
        http://localhost:8000/wp-content/uploads/2025/11/Bison_with_its_young-2560w-768x512.jpg    768w,
        http://localhost:8000/wp-content/uploads/2025/11/Bison_with_its_young-2560w-1536x1025.jpg 1536w,
        http://localhost:8000/wp-content/uploads/2025/11/Bison_with_its_young-2560w-2048x1366.jpg 2048w
      "
      sizes="(max-width: 1024px) 100vw, 1024px"
    />
  </figure>
</details>
--- before.html	2026-03-06 16:23:40
+++ after.html	2026-03-06 16:21:48
@@ -1,14 +1,13 @@
 <details
-  class="wp-block-details"
+  class="wp-block-details is-layout-flow wp-block-details-is-layout-flow"
 >
   <summary>Collapsed kitty</summary>
   <figure class="wp-block-image size-large">
     <img
-      fetchpriority="high"
       decoding="async"
       width="1024"
       height="771"
-      sizes="(max-width: 645px) 100vw, 645px"
+      fetchpriority="low"
       src="http://localhost:8000/wp-content/uploads/2026/03/PXL_20260302_201050363-1024x771.jpg"
       alt=""
       class="wp-image-415"
@@ -19,21 +18,22 @@
         http://localhost:8000/wp-content/uploads/2026/03/PXL_20260302_201050363-1536x1157.jpg 1536w,
         http://localhost:8000/wp-content/uploads/2026/03/PXL_20260302_201050363-2048x1542.jpg 2048w
       "
+      sizes="(max-width: 1024px) 100vw, 1024px"
     />
   </figure>
 </details>
 
 <details
-  class="wp-block-details"
+  class="wp-block-details is-layout-flow wp-block-details-is-layout-flow"
   open
 >
   <summary>Expanded bison</summary>
   <figure class="wp-block-image size-large">
     <img
+      fetchpriority="high"
       decoding="async"
       width="1024"
       height="683"
-      sizes="(max-width: 645px) 100vw, 645px"
       src="http://localhost:8000/wp-content/uploads/2025/11/Bison_with_its_young-2560w-1024x683.jpg"
       alt=""
       class="wp-image-37"
@@ -44,6 +44,7 @@
         http://localhost:8000/wp-content/uploads/2025/11/Bison_with_its_young-2560w-1536x1025.jpg 1536w,
         http://localhost:8000/wp-content/uploads/2025/11/Bison_with_its_young-2560w-2048x1366.jpg 2048w
       "
+      sizes="(max-width: 1024px) 100vw, 1024px"
     />
   </figure>
 </details>

Why?

An IMG in a collapsed DETAILS element should get fetchpriority=low to prevent it from ever competing with resources in the critical rendering path. Similarly, fetchpriority=low must be added to prevent WordPress from erroneously adding fetchpriority=high with the IMG is the first large image in the content via wp_get_loading_optimization_attributes().

How?

This implements a similar approach as #76208 by using a render callback to dynamically add fetchpriority=low when the block is set to be collapsed by default.

Testing Instructions

  1. Add two Details blocks to a post, with a large Image block in eac.
  2. Configure the second block to be open by default.
  3. Ensure that the IMG in the first Details block has fetchpriority=low, and the IMG in the second either has no fetchpriority at all or it has fetchpriority=high.

@westonruter westonruter added this to the Gutenberg 22.8 milestone Mar 7, 2026
@westonruter westonruter added [Type] Performance Related to performance efforts [Block] Details Affects the Details Block - used to display content which can be shown/hidden labels Mar 7, 2026
@github-actions github-actions bot added the [Package] Block library /packages/block-library label Mar 7, 2026
@github-actions
Copy link

github-actions bot commented Mar 7, 2026

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.

Co-authored-by: westonruter <westonruter@git.wordpress.org>
Co-authored-by: t-hamano <wildworks@git.wordpress.org>

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

@westonruter
Copy link
Member Author

-  class="wp-block-details"
+  class="wp-block-details is-layout-flow wp-block-details-is-layout-flow"

It's not clear to me why these class names are being added.

@westonruter westonruter changed the title Add fetchpriority=low to IMG tags in collapsed Details blocks Add fetchpriority=low to IMG tags in collapsed Details blocks Mar 7, 2026
@github-actions
Copy link

github-actions bot commented Mar 9, 2026

Flaky tests detected in b8e8442.
Some tests passed with failed attempts. The failures may not be related to this commit but are still reported for visibility. See the documentation for more information.

🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/22883346397
📝 Reported issues:

Copy link
Contributor

@t-hamano t-hamano left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

-  class="wp-block-details"
+  class="wp-block-details is-layout-flow wp-block-details-is-layout-flow"

It's not clear to me why these class names are being added.

Because the Details block supports blockGap, the is-layout-flow (wp-block-details-is-layout-flow) class should be dynamically added regardless of whether the block has a server-side rendering callback.

In fact, these classes are added to the Details block when the Gutenberg plugin is disabled. So this is a problem specific to the Gutenberg plugin.

But why aren't these classes added when the Gutenberg plugin is enabled? Perhaps at least some layout-related CSS classes aren't added to the block when the following conditions are met:

  • The Gutenberg plugin is enabled
  • The block doesn't have server-side rendering

register_block_type_from_metadata(
__DIR__ . '/details',
array(
'render_callback' => 'render_block_core_details',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about using the render_block_core/details filter instead, to give consumers the freedom to opt out of this processing?

function block_core_details_change_img_fetchpriority() {
	// 
}
add_filter( 'render_block_core/details', 'block_core_details_change_img_fetchpriority' );

function register_block_core_details() {
	register_block_type_from_metadata( __DIR__ . '/details' );
}
add_action( 'init', 'register_block_core_details' );

There's been a similar discussion about this before. #71207 (comment)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Works for me. How about 575c4a4?

Co-authored-by: t-hamano <wildworks@git.wordpress.org>
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a server-side render filter for the core/details block to ensure images inside collapsed <details> don’t receive high network priority, addressing an LCP/priority regression where hidden images can erroneously get fetchpriority="high".

Changes:

  • Introduces a render_block_core/details filter that sets fetchpriority="low" on all <img> tags when showContent is false (collapsed by default).
  • Registers the core/details block on init via metadata registration (consistent with other block-library PHP registrations).
  • Adds PHPUnit coverage for collapsed vs expanded Details rendering expectations.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
packages/block-library/src/details/index.php Adds a render filter to force fetchpriority="low" for images in collapsed Details blocks and registers the block on init.
phpunit/blocks/render-block-details-test.php Adds unit tests asserting fetchpriority behavior for collapsed vs expanded Details blocks.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

westonruter and others added 4 commits March 9, 2026 18:43
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Copy link
Contributor

@t-hamano t-hamano left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@t-hamano t-hamano added the Backport to WP 7.0 Beta/RC Pull request that needs to be backported to the WordPress major release that's currently in beta label Mar 10, 2026
@westonruter westonruter merged commit 9660efe into trunk Mar 10, 2026
45 checks passed
@westonruter westonruter deleted the fix/collapsed-details-img-fetchpriority branch March 10, 2026 02:35
@github-actions github-actions bot removed the Backport to WP 7.0 Beta/RC Pull request that needs to be backported to the WordPress major release that's currently in beta label Mar 10, 2026
gutenbergplugin pushed a commit that referenced this pull request Mar 10, 2026
…6269)

* Add fetchpriority=low to IMG tags in collapsed Details blocks

* Clarify comments

* Add unit tests for Details block

* Use filter instead of render callback for Details block

Co-authored-by: t-hamano <wildworks@git.wordpress.org>

* Remove parens from covers tag

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Use not-same assertion instead of null

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Add test case to preserve fetchpriority=high in expanded Details block

* End comment with period not comma

---------

Co-authored-by: t-hamano <wildworks@git.wordpress.org>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

Co-authored-by: westonruter <westonruter@git.wordpress.org>
Co-authored-by: t-hamano <wildworks@git.wordpress.org>
@github-actions github-actions bot added the Backported to WP Core Pull request that has been successfully merged into WP Core label Mar 10, 2026
@github-actions
Copy link

I just cherry-picked this PR to the wp/7.0 branch to get it included in the next release: 1f74bae

pento pushed a commit to WordPress/wordpress-develop that referenced this pull request Mar 12, 2026
This updates the pinned hash from the `gutenberg` from `9b8144036fa5faf75de43d4502ff9809fcf689ad` to `8c78d87453509661a9f28f978ba2c242d515563b`.

The following changes are included:

- Navigation Editor: Allow any blocks to be inserted by gating contentOnly insertion rules to section blocks (WordPress/gutenberg#76189)
- Add `fetchpriority=low` to `IMG` tags in collapsed Details blocks (WordPress/gutenberg#76269)
- Connectors: Add logo URL support for custom AI providers (WordPress/gutenberg#76190)
- Cover Block: Add a playlist parameter to loop YouTube background videos. (WordPress/gutenberg#76004)
- Connectors: Memoize getConnectors selector (WordPress/gutenberg#76339)
- HTML Block: Fix broken layout (WordPress/gutenberg#76278)
- Tests: Skip connector logo URL tests when AI Client is unavailable (WordPress/gutenberg#76343)
- Navigation Overlay: Explicitly set fetchpriority for images (WordPress/gutenberg#76208)
- Connectors: Show API key source for env vars and wp-config constants (WordPress/gutenberg#76355)
- Connectors: Move API key validation and masking to REST dispatch level (WordPress/gutenberg#76327)
- Connectors: Replace apiFetch with core-data store selectors (WordPress/gutenberg#76333)
- Do not sync local attributes (WordPress/gutenberg#76267)
- Add `fetchpriority=low` to `IMG` tags in collapsed Accordion Item blocks (WordPress/gutenberg#76336)
- Implement disconnection debounce after initial connection (WordPress/gutenberg#76114)
- Allow Post Content to be edited when 'Show template' is active and Post content is nested in a Template Part (WordPress/gutenberg#76305)
- Fix: Document Bar: Back button flickers (WordPress/gutenberg#76320)
- RTC: Move event hooks from editor to core-data (WordPress/gutenberg#76358)
- fix(navigation): prevent right-justified submenu overflow in custom overlays (WordPress/gutenberg#76360)
- Connectors: Add connectors registry for extensibility (WordPress/gutenberg#76364)
- Connectors: Add empty state when no connectors are registered (WordPress/gutenberg#76375)
- Temp: Disable RTC in the site editor (WordPress/gutenberg#76223)
- Connectors: Add AI Experiments plugin callout with install/activate functionality (WordPress/gutenberg#76379)
- Editor: Polish real-time collaboration presence UI and move Avatar to editor package (WordPress/gutenberg#75652) (WordPress/gutenberg#76365)
- RTC: Add collaborator selection highlighting in rich text (WordPress/gutenberg#76107)
- Sync changes from `wp_enqueue_global_styles()` to Gutenberg override (WordPress/gutenberg#76127)
- [RTC] Fix performance regression on post save (WordPress/gutenberg#76370)
- Media: Enable AVIF support for client-side uploads (WordPress/gutenberg#76371)
- Connectors: Move plugin status computation to script module data (WordPress/gutenberg#76409)
- Revisions: Skip rendered fields in REST API responses (WordPress/gutenberg#76347)
- E2E Tests: Add connector setup flow tests with test AI provider (WordPress/gutenberg#76433)
- RTC: Place sync connection modal in front of popover (WordPress/gutenberg#76431)
- Connectors: Sync PHP code with WordPress Core (WordPress/gutenberg#76443)
- Editor: Show own presence in collaborative editing sessions (WordPress/gutenberg#76413) (WordPress/gutenberg#76445)

A full list of changes can be found on GitHub: https://github.com/WordPress/gutenberg/compare/9b8144036fa5faf75de43d4502ff9809fcf689ad…8c78d87453509661a9f28f978ba2c242d515563b.

Log created with:

git log --reverse --format="- %s" 9b8144036fa5faf75de43d4502ff9809fcf689ad..8c78d87453509661a9f28f978ba2c242d515563b | sed 's|#\([0-9][0-9]*\)|https://github.com/WordPress/gutenberg/pull/\1|g; /github\.com\/WordPress\/gutenberg\/pull/!d' | pbcopy

See #64595.


git-svn-id: https://develop.svn.wordpress.org/trunk@61988 602fd350-edb4-49c9-b593-d223f7449a82
markjaquith pushed a commit to markjaquith/WordPress that referenced this pull request Mar 12, 2026
This updates the pinned hash from the `gutenberg` from `9b8144036fa5faf75de43d4502ff9809fcf689ad` to `8c78d87453509661a9f28f978ba2c242d515563b`.

The following changes are included:

- Navigation Editor: Allow any blocks to be inserted by gating contentOnly insertion rules to section blocks (WordPress/gutenberg#76189)
- Add `fetchpriority=low` to `IMG` tags in collapsed Details blocks (WordPress/gutenberg#76269)
- Connectors: Add logo URL support for custom AI providers (WordPress/gutenberg#76190)
- Cover Block: Add a playlist parameter to loop YouTube background videos. (WordPress/gutenberg#76004)
- Connectors: Memoize getConnectors selector (WordPress/gutenberg#76339)
- HTML Block: Fix broken layout (WordPress/gutenberg#76278)
- Tests: Skip connector logo URL tests when AI Client is unavailable (WordPress/gutenberg#76343)
- Navigation Overlay: Explicitly set fetchpriority for images (WordPress/gutenberg#76208)
- Connectors: Show API key source for env vars and wp-config constants (WordPress/gutenberg#76355)
- Connectors: Move API key validation and masking to REST dispatch level (WordPress/gutenberg#76327)
- Connectors: Replace apiFetch with core-data store selectors (WordPress/gutenberg#76333)
- Do not sync local attributes (WordPress/gutenberg#76267)
- Add `fetchpriority=low` to `IMG` tags in collapsed Accordion Item blocks (WordPress/gutenberg#76336)
- Implement disconnection debounce after initial connection (WordPress/gutenberg#76114)
- Allow Post Content to be edited when 'Show template' is active and Post content is nested in a Template Part (WordPress/gutenberg#76305)
- Fix: Document Bar: Back button flickers (WordPress/gutenberg#76320)
- RTC: Move event hooks from editor to core-data (WordPress/gutenberg#76358)
- fix(navigation): prevent right-justified submenu overflow in custom overlays (WordPress/gutenberg#76360)
- Connectors: Add connectors registry for extensibility (WordPress/gutenberg#76364)
- Connectors: Add empty state when no connectors are registered (WordPress/gutenberg#76375)
- Temp: Disable RTC in the site editor (WordPress/gutenberg#76223)
- Connectors: Add AI Experiments plugin callout with install/activate functionality (WordPress/gutenberg#76379)
- Editor: Polish real-time collaboration presence UI and move Avatar to editor package (WordPress/gutenberg#75652) (WordPress/gutenberg#76365)
- RTC: Add collaborator selection highlighting in rich text (WordPress/gutenberg#76107)
- Sync changes from `wp_enqueue_global_styles()` to Gutenberg override (WordPress/gutenberg#76127)
- [RTC] Fix performance regression on post save (WordPress/gutenberg#76370)
- Media: Enable AVIF support for client-side uploads (WordPress/gutenberg#76371)
- Connectors: Move plugin status computation to script module data (WordPress/gutenberg#76409)
- Revisions: Skip rendered fields in REST API responses (WordPress/gutenberg#76347)
- E2E Tests: Add connector setup flow tests with test AI provider (WordPress/gutenberg#76433)
- RTC: Place sync connection modal in front of popover (WordPress/gutenberg#76431)
- Connectors: Sync PHP code with WordPress Core (WordPress/gutenberg#76443)
- Editor: Show own presence in collaborative editing sessions (WordPress/gutenberg#76413) (WordPress/gutenberg#76445)

A full list of changes can be found on GitHub: https://github.com/WordPress/gutenberg/compare/9b8144036fa5faf75de43d4502ff9809fcf689ad…8c78d87453509661a9f28f978ba2c242d515563b.

Log created with:

git log --reverse --format="- %s" 9b8144036fa5faf75de43d4502ff9809fcf689ad..8c78d87453509661a9f28f978ba2c242d515563b | sed 's|#\([0-9][0-9]*\)|https://github.com/WordPress/gutenberg/pull/\1|g; /github\.com\/WordPress\/gutenberg\/pull/!d' | pbcopy

See #64595.

Built from https://develop.svn.wordpress.org/trunk@61988


git-svn-id: http://core.svn.wordpress.org/trunk@61270 1a063a9b-81f0-0310-95a4-ce76da25c4cd
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Backported to WP Core Pull request that has been successfully merged into WP Core [Block] Details Affects the Details Block - used to display content which can be shown/hidden [Package] Block library /packages/block-library [Type] Performance Related to performance efforts

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Image in collapsed Details block may erroneously get fetchpriority=high even though hidden

3 participants