Skip to content

Ensure IMG with fetchpriority=low does not get lazy-loaded, increase media count, or interfere with assigning fetchpriority=high#11196

Open
westonruter wants to merge 4 commits intoWordPress:trunkfrom
westonruter:trac-64823-fetchpriority-loading-optimization-attributes
Open

Ensure IMG with fetchpriority=low does not get lazy-loaded, increase media count, or interfere with assigning fetchpriority=high#11196
westonruter wants to merge 4 commits intoWordPress:trunkfrom
westonruter:trac-64823-fetchpriority-loading-optimization-attributes

Conversation

@westonruter
Copy link
Member

@westonruter westonruter commented Mar 6, 2026

Trac ticket: https://core.trac.wordpress.org/ticket/64823

With WordPress/gutenberg#76208 checked out and there are 5 large images added to a Navigation Overlay and 5 large images in the post content, given the following script being run in the console:

Array.from(document.querySelectorAll(".wp-site-blocks img")).map((img) => {
  return {
    insideNavOverlay: !!img.closest(".wp-block-navigation__overlay-container"),
    loading: img.loading,
    fetchPriority: img.fetchPriority,
  };
});
Before ❌
[
    {
        "insideNavOverlay": true,
        "loading": "auto",
        "fetchPriority": "low"
    },
    {
        "insideNavOverlay": true,
        "loading": "auto",
        "fetchPriority": "low"
    },
    {
        "insideNavOverlay": true,
        "loading": "auto",
        "fetchPriority": "low"
    },
    {
        "insideNavOverlay": true,
        "loading": "auto",
        "fetchPriority": "low"
    },
    {
        "insideNavOverlay": true,
        "loading": "auto",
        "fetchPriority": "low"
    },
    {
        "insideNavOverlay": false,
        "loading": "lazy",
        "fetchPriority": "auto"
    },
    {
        "insideNavOverlay": false,
        "loading": "lazy",
        "fetchPriority": "auto"
    },
    {
        "insideNavOverlay": false,
        "loading": "lazy",
        "fetchPriority": "auto"
    },
    {
        "insideNavOverlay": false,
        "loading": "lazy",
        "fetchPriority": "auto"
    },
    {
        "insideNavOverlay": false,
        "loading": "lazy",
        "fetchPriority": "auto"
    }
]
After ✅
[
    {
        "insideNavOverlay": true,
        "loading": "auto",
        "fetchPriority": "low"
    },
    {
        "insideNavOverlay": true,
        "loading": "auto",
        "fetchPriority": "low"
    },
    {
        "insideNavOverlay": true,
        "loading": "auto",
        "fetchPriority": "low"
    },
    {
        "insideNavOverlay": true,
        "loading": "auto",
        "fetchPriority": "low"
    },
    {
        "insideNavOverlay": true,
        "loading": "auto",
        "fetchPriority": "low"
    },
    {
        "insideNavOverlay": false,
        "loading": "auto",
        "fetchPriority": "high"
    },
    {
        "insideNavOverlay": false,
        "loading": "auto",
        "fetchPriority": "auto"
    },
    {
        "insideNavOverlay": false,
        "loading": "auto",
        "fetchPriority": "auto"
    },
    {
        "insideNavOverlay": false,
        "loading": "lazy",
        "fetchPriority": "auto"
    },
    {
        "insideNavOverlay": false,
        "loading": "lazy",
        "fetchPriority": "auto"
    }
]

The diff shows the changes to the first three images in the content (outside of the navigation overlay):

--- before.json	2026-03-06 15:32:18
+++ after.json	2026-03-06 15:32:27
@@ -26,17 +26,17 @@
     },
     {
         "insideNavOverlay": false,
-        "loading": "lazy",
-        "fetchPriority": "auto"
+        "loading": "auto",
+        "fetchPriority": "high"
     },
     {
         "insideNavOverlay": false,
-        "loading": "lazy",
+        "loading": "auto",
         "fetchPriority": "auto"
     },
     {
         "insideNavOverlay": false,
-        "loading": "lazy",
+        "loading": "auto",
         "fetchPriority": "auto"
     },
     {

Fixes:

  1. Preserve fetchpriority=high being assigned to the first large image outside of the Navigation Overlay.
  2. Prevent adding loading=lazy on the first three images in the content.

Use of AI Tools

  • None for authoring
  • Copilot for review

This Pull Request is for code review only. Please keep all other discussion in the Trac ticket. Do not merge this Pull Request. See GitHub Pull Requests for Code Review in the Core Handbook for more details.

@github-actions
Copy link

github-actions bot commented Mar 6, 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.

Core Committers: Use this line as a base for the props when committing in SVN:

Props westonruter.

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

@github-actions
Copy link

github-actions bot commented Mar 6, 2026

Test using WordPress Playground

The changes in this pull request can previewed and tested using a WordPress Playground instance.

WordPress Playground is an experimental project that creates a full WordPress instance entirely within the browser.

Some things to be aware of

  • All changes will be lost when closing a tab with a Playground instance.
  • All changes will be lost when refreshing the page.
  • A fresh instance is created each time the link below is clicked.
  • Every time this pull request is updated, a new ZIP file containing all changes is created. If changes are not reflected in the Playground instance,
    it's possible that the most recent build failed, or has not completed. Check the list of workflow runs to be sure.

For more details about these limitations and more, check out the Limitations page in the WordPress Playground documentation.

Test this pull request with WordPress Playground.

@westonruter westonruter requested a review from Copilot March 7, 2026 01:34
@westonruter
Copy link
Member Author

cc @mukeshpanchal27

Copy link

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

Updates core loading-optimization heuristics to treat img[fetchpriority=low] as a special case so it won’t be lazy-loaded, won’t affect the content media count, and won’t interfere with assigning fetchpriority=high to the first in-viewport large image.

Changes:

  • Extend wp_get_loading_optimization_attributes() to recognize existing fetchpriority=low and avoid adding loading="lazy" / incrementing media count.
  • Add PHPUnit coverage to ensure fetchpriority=low images don’t influence the “first N images not lazy-loaded” and high-priority selection logic.

Reviewed changes

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

File Description
src/wp-includes/media.php Adds fetchpriority=low handling in loading optimization logic and documents the behavior.
tests/phpunit/tests/media.php Adds helper + additional assertions to cover fetchpriority=low interactions across contexts/loops.

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

westonruter and others added 3 commits March 6, 2026 17:59
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
),
wp_get_loading_optimization_attributes( 'img', $attr, $context ),
"Expected first image to not be lazy-loaded. First large image get's high fetchpriority."
"Expected first image to not be lazy-loaded. First large image gets high fetchpriority."
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
"Expected first image to not be lazy-loaded. First large image gets high fetchpriority."
'Expected first image to not be lazy-loaded. First large image gets high fetchpriority.'

* or it may be occluded in a non-initial carousel slide. Such images must not be lazy-loaded because the browser
* has no heuristic to know when to start loading them before the user needs to see them.
*/
$maybe_in_viewport = false;
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
$maybe_in_viewport = false;
$maybe_in_viewport = false;
$loading_attrs['fetchpriority'] = 'low';

Shell we add here instead of separate condition?

// Preserve fetchpriority=low.
if ( $is_low_fetchpriority ) {
	$loading_attrs['fetchpriority'] = 'low';
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants