Proposal for enhancing LCP image performance with the fetchpriority attribute in WordPress core
This post proposes adding the
fetchpriority=”high” attribute to LCP images in WordPress core to enhance LCP performance. The proposal was created as a collaboration between members of the Core Performance Team.
fetchpriority attribute is a standard HTML attribute that can be used to indicate to the browser that a given resource should have a particular priority for when it should be considered for loading. Most commonly, using the attribute is recommended with a value of “high”, only on the most important image on a page.
It is a performance best practice to provide
fetchpriority=”high” on the single image that is the “Largest Contentful Paint element” in the HTML markup, to indicate to the browser that this image should be prioritized over other resources that would compete with it for network bandwidth.
Largest Contentful Paint (LCP) is one of the three Core Web Vitals metrics, and it represents how quickly the main content of a web page is loaded. Specifically, LCP measures the time from when the user initiates loading the page until the largest image or text block is rendered within the viewport.Quoted from this article about optimizing LCP
As mentioned above, the Largest Contentful Paint element can take different forms, it may be an image, text, video, or other resource. However, most commonly the LCP element on WordPress sites is an image, concretely 42.4% on desktop and 38.2% on mobile based on HTTP Archive data from February 2023. Of those sites, less than 0.03% have
fetchpriority=”high” on their LCP image, so it is safe to say that introducing support in WordPress core will benefit almost all of them.
You can learn more about the
fetchpriority attribute and how it should be used to optimize image performance in this article.
WordPress core already comes with a mechanism to detect which image(s) not to lazy-load because they are likely in the viewport, which includes the potential LCP image. Bringing
fetchpriority=”high” to images in WordPress core should make use of that existing logic for the
loading attribute, which was added in WordPress 5.9. However, the two attributes should still function independently of each other. Furthermore, a few additional aspects need to be taken into consideration and implemented as additional heuristics that only apply to the
fetchpriority attribute, but not the
Initially, the two attributes may seem like they are opposites. An image that should be lazy-loaded should not have a high priority, and vice-versa. The usage of
fetchpriority=”high” however needs to be a bit more nuanced: It should only be loaded on the single most important image on the page. This is different from
loading=”lazy” which should be omitted on any image above the fold — which sometimes may be just the LCP image, while in other cases it may be multiple images.
In other words,
fetchpriority=”high” should only ever appear on a single image at most.
fetchpriority attribute is available on a few different HTML elements, the scope of this proposal is only to use the attribute on images, specifically to add it to the likely LCP image of a page so that the browser knows to load it earlier than other resources that may be competing with it.
Based on benchmarks conducted by members of the Core Performance Team, adding
fetchpriority=”high” to the LCP image typically improves LCP performance by 5-10%, which is a notable win for adding a simple attribute to an image tag. In some instances the enhancements can even be close to 30%, like in an example from the aforementioned article.
fetchpriority attribute is a relatively new attribute first introduced in 2022, it was standardized in February 2023 and is supported by all Chromium based browsers, which make up for ~70% of browser usage based on caniuse.com. Support was recently added in WebKit, and is currently available in the Safari 167 Tech Preview. Firefox has expressed positive feedback on the feature, and a ticket to support it is available. Despite not every major browser supporting the attribute, it is a progressive enhancement, i.e. fully backward compatible: A browser that does not understand the attribute will ignore it, and its presence won’t cause any adverse effects.
Effectively, this enhancement is only about adding the
fetchpriority=”high” attribute to the LCP image, which does not pose any risk of breaking backward compatibility.
Default behavior and customization
Similar to how WordPress core handles omitting the
loading attribute on specific images, it should add the
fetchpriority attribute by default on the LCP image based on server-side heuristics. While the exact heuristics are still being defined, it should be noted that the two attributes will never be used on the same image as they should be mutually exclusive.
Developers will be able to customize where the attribute should be used, e.g. when using the functions
get_the_post_thumbnail(), both of which should receive support for the attribute. The default addition of the attribute to in-content images will also be customizable using a new filter, which will likely be similar to existing image attribute filters like
fetchpriority=”high”, images can also be prioritized through other means, e.g. a
link[rel=”preload”] tag in the head, or a
Link response header. While those two approaches in principle allow the browser to know about loading the image even earlier, in practice there isn’t a notable difference, especially when using the tag, as at that point the entire HTML will already be loaded.
Either of the alternative approaches would furthermore require WordPress core knowing about the image in the page load lifecycle before it is even included in the output, which makes them more complex to implement in a way that is not justifiable given the little benefits it would bring over using
fetchpriority=”high” on the actual image tag.
Contributing and testing this enhancement
An early version of the proposed enhancement can already be tested through the Performance Lab plugin, by enabling its Fetchpriority module. It should be noted that the module is still being refined with additional heuristics to detect the LCP image, and since it is part of a plugin rather than within WordPress core, the customization options outlined above cannot be part of this early implementation. It should furthermore be noted that the plugin implementation relies heavily on WordPress core’s lazy-loading heuristics, whereas the plan for the eventual core implementation would be to decouple the two.
A WordPress Core Trac ticket #58235 has been opened, and a pull request for WordPress core, including the aforementioned customization options will be worked on soon.
Your testing and feedback is much appreciated. Please share your ideas, questions and thoughts either in a comment on this post, in the plugin’s support forum on wordpress.org, or on the GitHub repository.
Props to @tweetythierry @adamsilverstein @addyosmani @joemcgill @thekt12 for review and proofreading.