In WordPress 6.1 and 6.2 there were introduced several “performance boost” changes. In particular, applying the decoding=”async” attribute for all images has become a significant problem for my and maybe your sites. This feature, intended as a performance boost, could harm the critical Largest Contentful Paint (LCP) metric.
Natively, WordPress adds the decoding="async"
attribute to every image by default. This attribute tells the browser to decode the image asynchronously, allowing other tasks to run in the meantime. This might sound like a good thing for performance, but it can negatively impact LCP when not managed correctly. LCP is a critical Core Web Vital that measures when the main content of a webpage has finished rendering on the screen. Delaying image decoding, especially for images that contribute to the LCP, can result in a worse LCP score, affecting both the user experience and potentially your site’s SEO.
Understanding Decoding Types: Auto, Sync, Async
In modern web development, there are three types of image decoding: auto
, sync
, and async
.
auto
: The browser decides when to decode the image based on its own heuristics. It’s the default behavior if the decoding attribute is not specified.sync
: The image is decoded before it’s painted on the screen. This can cause layout jank if the image is large, but it guarantees it is ready once needed.async
: The image decoding is delayed until other tasks have been handled, which can improve overall load times but may delay critical images.
In a perfectly optimized website, each image should have its decoding type set based on its importance to the page layout, visibility, and user interaction. However, by design, WordPress sets every image to async
, irrespective of other parameters such as loading="eager"
or fetchPriority="high"
, which can result in less-than-ideal LCP scores.
To solve this issue, we can use a couple of approaches to refine WordPress’s behavior. Both of these solutions involve removing the decoding
attribute from images when they have certain other attributes set.
Snippets
Snippet 1: Modifying wp_get_attachment_attributes
Here, we’ll adjust the attributes directly when WordPress is generating the image HTML:
This snippet hooks into WordPress’s image HTML generation process, checks for the fetchPriority
and loading
attributes, and removes the decoding
attribute if necessary. There’s also an option to exclude certain images by adding a specific class to them.
Snippet 2: Post-Processing Rendered HTML
Alternatively, we could process the HTML after WordPress has generated it:
This snippet is a bit of a heavier solution, as it operates on the HTML after it’s already been rendered. However, it has the benefit of also working on images that weren’t handled by WordPress’s native functions, providing a more global solution.
Snippet 3: Disable decoding=async
Lastly, it’s important to note that there’s another way to tackle this problem: disabling adding decoding entirely. WordPress has a built-in filter that can be used to disable this feature. However, while it’s a simple solution, it’s also quite drastic and might lead to other performance issues, so use it with care.
Remember, the goal here isn’t to demonize lazy loading or the decoding="async"
attribute. They are powerful tools for improving web performance. The key is using them judiciously and ensuring they don’t inadvertently hurt the metrics that matter most for user experience and SEO, such as the Largest Contentful Paint. By understanding these aspects and making careful adjustments, you can harness their benefits without compromising your site’s performance.
P.S. If I saved you time please feel free to make a donation via my PayPal (invoice can be issued upon request). Any contribution, big or small, is greatly appreciated and helps keep these resources free for everyone. Thank you for your support!
P.P.S. Blog post is written with the help of Chat GPT-4.