The last two chapters of the 2022 Web Almanac were released this week – Structured Data and Performance, completing the 729-page ebook of the report. The WordPress-specific chapter was published earlier this month with metrics that indicate adoption is growing.
The Performance chapter was written by Etsy performance engineer Melissa Ada and Google web transparency engineer Rick Viscomi. Performance metrics in the chapter focus on Core Web Vitals (CWV), which Google introduced in 2020 and made a ranking signal in 2021. They used the public Chrome UX Report (CrUX) dataset for the report, which collects data from eligible websites – publicly discoverable sites with an undisclosed minimum number of visitors.
Most of the data concerns the performance of the web as a whole over time, but the 2022 Web Almanac highlighted one specific concern regarding WordPress sites’ use of lazy-loading and its impact on LCP performance. Google defines Largest Contentful Paint metric (LCP) metrics as “the render time of the largest image or text block visible within the viewport, relative to when the page first started loading.”
Lazy-loading is a good thing when used correctly, but these stats strongly suggest that there’s a major opportunity to improve performance by removing this functionality from LCP images in particular.
WordPress was one of the pioneers of native lazy-loading adoption, and between versions 5.5 and 5.9, it didn’t actually omit the attribute from LCP candidates. So let’s explore the extent to which WordPress is still contributing to this anti-pattern.
According to the CMS chapter, WordPress is used by 35% of pages. So it’s surprising to see that 72% of pages that use native lazy-loading on their LCP image are using WordPress, given that a fix has been available since January 2022 in version 5.9. One theory that needs more investigation is that plugins may be circumventing the safeguards built into WordPress core by injecting LCP images onto the page with the lazy-loading behavior.
Similarly, a disproportionately high percentage of pages that use custom lazy-loading are built with WordPress at 54%. This hints at a wider issue in the WordPress ecosystem about lazy-loading overuse. Rather than being a fixable bug localized to WordPress core, there may be hundreds or thousands of separate themes and plugins contributing to this anti-pattern.
Prior to WordPress 5.9, WordPress’ default of lazy loading implementation was causing slower LCP performance, because it had been applied too aggressively and was lazy-loading images above the fold. In 5.9, WordPress shipped a fix that more eagerly loads images within the initial viewport while lazy-loading the rest. That’s why results that show WordPress sites overusing lazy-loading are surprising.
“Admittedly, ‘lazy-overloading’ a hard problem to solve,” Viscomi said in his Twitter thread analysis. “We don’t always know whether an image will be the LCP. WordPress core sets it on every image by default and uses heuristics to unset it. Nearly 3/4 of pages that natively lazy-load images are on WordPress.”
In 2020, Viscomi remarked on how quickly the adoption of native image lazy-loading shot up after WordPress 5.5 was released in August of that year with images lazy-loaded by default. WordPress has been driving adoption of this feature, which is why any implementation “anti-pattern,” as Viscomi characterized it, has an outsized effect on the performance of the web.
“What gives, WordPress?” Viscomi said. “My theory is that it’s not the core heuristics that are wrong, it’s the plugins. Also, keep in mind that the majority of pages that even use lazy-loading are WP.
“To support the plugin theory, let’s look at custom lazy-loading of LCP: More than half of the pages that do it are built with WordPress. WordPress is ‘only’ a third of the web, so there’s clearly something going on with JS-based lazy-overloading in WP.”
On WordPress.org there are multiple pages of performance, caching, and image and video optimization plugins that are using lazy-loading in some way. Plugin and theme developers who are using lazy-loading in their extensions may want to test their implementations to see if they are having a negative impact on LCP performance.