Largest Contentful Paint In WordPress: Advanced Guide To Improving LCP Score

Largest contentful paint wordpress

Largest contentful paint is the core web vital people struggle with most.

Google’s video on optimizing LCP is a great watch and breaks LCP into 4 parts: TTFB, resource load delay, resource load time, and element render delay. Philip gives solid recommendations to improve each part, but they’re not WordPress-specific (pretty much why I wrote this tutorial).

For example, it’s hard to mention TTFB without talking about Cloudflare Enterprise + full page caching. Cache plugins have specific settings that can help (or hurt) LCP. Themes/plugins that add lots of CSS/JavaScript impact it too. Follow these tips and I bet your LCP will be under 2.5s.

LCP measures how long it takes the main content to load. People struggle with LCP because there are lots of factors. Your above the fold content is a good place to start.

Largest Contentful Paint Score
0 – 2.5s Good
2.5 – 4s Needs Improvement
Over 4s Poor

 

1. Learn Which LCP Parts You Need To Work On

Largest contentful paint is broken down into 4 sub-parts. Skip to 12:40 in Google’s video for quick tips to improve each part. Otherwise, I listed tips below.

Largest contentful paint breakdown
Credit: Google’s LCP breakdown
LCP Sub-Part Factors LCP %
TTFB Primarily hosting and CDNs + full page caching ~40%
Resource load delay Exclude above the fold content from optimizations, resource hints <10%
Resource load time Reduce image/CSS/JS sizes, critical CSS, CDN, cache expiration ~40%
Element render delay Render-blocking CSS/JS, JS file size, font-display optional <10%

Tools

  • KeyCDN Performance Test – measures TTFB in 10 global locations.
  • Waterfall Chart – nice visualization showing which files are contributing to LCP.
  • PSI Recommendations – many recommendations in PageSpeed Insights are correlated with LCP. Fixing recommendations shown in opportunities/diagnostics reports can help.
  • Chrome Dev Tools Coverage Report – large, unoptimized CSS/JS files are one of the biggest LCP factors. This can help you find which plugins and third-party JavaScript take longest to load. The plugin names and third-party domains are usually listed in the URL.
Chrome dev tools lcp waterfall time 1
Chrome Dev Tools Waterfall chart shows files loading within the LCP time

 

2. Exclude Above The Fold Images From Lazy Load

Above the fold images should be shown immediately, but lazy load delays them and adds to the “resource load delay” part of LCP.

It can be time consuming to go through every single page/post and exclude these images manually. While logos and top sidebar images may be universal across most of your website, your top post image (#3 in the screenshot below) is often unique for every single page and post.

Above the fold images

They also happen to be my largest contentful paint element for most posts:

Largest contentful paint element

Preloading critical images is usually the best method. Not only does it preload above the fold images, but it also excludes them from lazy load. It’s supported by Perfmatters and FlyingPress. Just set the number of images usually shown above the fold and the plugin will handle the rest.

Preload critical images perfmatters

You can also exclude leading images, but it won’t preload them.

Exclude leading images from lazy load

If your cache plugin doesn’t support either of these, you’ll need to manually go through your pages/posts, copy all image URLs loading above the fold, then exclude them manually. Some cache plugins have exclusion methods which you should be able to find in their documentation.

Background Images

Background images aren’t lazy loaded since they’re often loaded from a separate CSS file. Some cache plugins have a lazy-bg helper class to lazy load them while WP Rocket requires moving them to inline HTML. Since they’re not lazy loaded, there’s usually no need to exclude above the fold background images, but you’ll need to lazy load these manually if they load below the fold.

Elementor Image Widgets

Elementor image widgets aren’t excluded from lazy load by default since they don’t use img tags. Cache plugins sometimes have a skip-lazy helper class for excluding images manually.

Optimizing Above The Fold Images Is Key

Just like you would optimize any image on your site, it’s even more important to do this for above the fold images. Compress them, use correct dimensions, faster image formats (i.e. WebP), and serve smaller image sizes to mobile devices via CDNs or an adaptive images plugin.

 

3. Prioritize Above The Fold Images

If you’re preloading critical images shown in the previous step, you shouldn’t need to do anything since above the fold images are already being prioritized and excluded from lazy load.

However, preload has drawbacks and Google recommends only using it for background LCP images, then using fetchpriority especially for your LCP image shown in PageSpeed Insights.

Here, we’re giving the LCP image a high fetchpriority while using the faster WebP version.

<link fetchpriority="high" rel="preload" href="/LCP-image.webp" as="image">

As of writing this, FlyingPress is the only cache plugin I know that supports fetchpriority shown in their changelog in version 3.9.0.

Another Challenge For Background Images

If your LCP image is a background image and loads in a separate CSS file like Elementor does, your LCP image won’t be preloaded. You need to move the background image to inline HTML and preload it, or preload both the background image and the CSS file the image is located in.

“To eliminate unnecessary resource load delay, your LCP resource should always be discoverable from the HTML source. In cases where the resource is only referenced from an external CSS or JavaScript file, then the LCP resource should be preloaded.”

 

4. Reduce CSS/JavaScript Sizes

Resource load time is 40% of LCP and CSS/JS are usually your largest files.

View your Chrome Dev Tools coverage report and look at the URLs which usually tell you whether certain plugins, themes, third-party JavaScript, or other files add the most bytes.

Css javascript chrome dev tools

Summary

  • Themes – the last thing you want to do is start with a bloated theme/page builder and install multiple heavy page builder plugins. Elementor/Divi are notoriously slow while Gutenberg is lightweight. GeneratePress, Blocksy, Kadence for the win.
  • Plugins – the coverage report shows which plugins add the most CSS/JavaScript. Try moving plugin-dependent content below the fold like social sharing plugins and image galleries. Mega menus are awful for LCP since not only do they add CSS/JS, but they also add it above the fold on every single page of your website.
  • Remove Unused CSS – WP Rocket’s is slower than FlyingPress, Perfmatters, and LiteSpeed Cache as it loads used CSS inline instead of a separate file. Separate file is faster for visitors since the file can be cached and it doesn’t increase HTML size.
  • Minify – strips unnecessary characters from CSS/JS which reduces their file size.
  • Third-Party Code – start by hosting files locally (fonts, analytics, using local avatars for comments, YouTube preview images and thumbnails, etc). The rest of third-party code can usually be delayed. A common reason you’ll see this error in PSI is overtracking. Do you really need Google Analytics, Tag Manager, Heatmaps, Facebook Pixel, New Relic, and other tracking tools? Consider removing some of them. Perfmatters does an excellent job at reducing the size of GA tracking codes.
  • Asset unloading plugins – Perfmatters and Asset CleanUp are two popular plugins for removing individual CSS/JS files (or entire plugins) on specific content.
  • Page builder optimizations – Elementor Experiments and Divi’s built-in performance settings have several options to reduce the size of CSS, JS, and fonts.
  • Code header in CSS – don’t use slow page builders (or plugins) for your header or menus. Code them in CSS instead. It’s much faster than bloated page builder code.
  • Remove files you don’t use – icons, Gutenberg CSS, jQuery, emojis, elementor-dialog, and other individual files can be removed/dequeued when not using them.
Fastest wordpress themes
Some themes/page builders load more resources than others
Disable social sharing plugins perfmatters
Some plugins load CSS/JS across your site when they can be disabled on specific pages/posts
Elementor experiments
Page builders often have built-in settings to reduce CSS/JS

 

5. Reduce TTFB

TTFB is 40% of LCP and explained in Google’s video at 5:24.

Measuring TTFB in 10 global locations using KeyCDN is a good starting point.

Rocket. Net keycdn performance test 1

Hosting, CDNs, and full page caching are arguably the top 3 ways to improve TTFB.

There are many services that can help: APO (or Super Page Cache for Cloudflare), Cloudflare Enterprise (i.e. through Rocket.net, Cloudways, or Kinsta), and FlyingProxy are popular choices. Then you have QUIC.cloud’s CDN which also uses HTML caching if you’re on a LiteSpeed server.

Rocket.net is what I use.

They use Cloudflare Enterprise + full page caching (unlike Cloudways/Kinsta). When viewing specs, they give you more resources (32 cores + 128GB RAM), NVMe, and they don’t limit PHP workers because only about 10% of traffic hits your origin server (which is why they allow up to 25x more monthly visits than Kinsta). They were a top performer in Kevin Ohashi’s benchmarks while Cloudways/Kinsta weren’t. Cloudflare Enterprise + Redis is free on all plans and the CEO (Ben Gabler) has years of experience with Cloudflare/StackPath if you look into his background.

I try to keep things unbiased, but when something is clearly better, I try to call it how it is. You can read my full Rocket.net review if you have doubts.

  • Full page caching – caching HTML improved TTFB by 72% in Cloudflare’s APO test. You can do this with services like APO, Super Page Cache, or QUIC.cloud. A main benefit of APO (versus a cache everything rule) is the use of Workers KV database. FlyingProxy and SiteGround also use Cloudflare’s full page caching, although SiteGround has a history of TTFB issues and I don’t recommend them.
  • Cloudflare Enterprise – improves TTFB with Argo + Tiered Cache, prioritized routing, load balancing, and other premium Cloudflare features. Some third-party services do a better job of integrating Cloudflare Enterprise than others and also come with more features, so make sure to do your research before using a service.
  • Hosting specs – a host’s technology largely impacts TTFB. Most hosts have a “specs” page listing things like CPU cores, RAM, SSD/NVMe storage, etc Other times, specs are mentioned in their blog, inner pages, or TOS (for example, you can compare Rocket.net’s CPU/RAM vs. Kinsta’s CPU/RAM). Always compare specs.

Latency is also included in TTFB. Two simple ways to improve this are using a fast DNS like Cloudflare and tweaking Cloudflare SSL/TLS settings (using higher TLS versions for example).

 

6. Eliminate Render-Blocking CSS/JS

These contribute to “element render delay” which is 10% of LCP.

The easiest way to eliminate render-blocking resources is to view your PSI report and learn whether these files are from CSS or JavaScript (also take note of where they’re loading from).

Critical CSS loads above the fold CSS faster and most cache plugins have settings for it. You can use a critical CSS generator, but this isn’t preferred since critical CSS can be different depending on the page/post and changes if you make CSS changes where critical CSS needs to be updated.

Deferring JavaScript pushes JavaScript files into the footer so they’re loaded non render-blocking. Again, most cache plugins have a setting for this. If enabling it breaks your website, you should really try to exclude problematic files rather than disabling the setting completely.

Autoptimize and Async JavaScript are also good for handling render-blocking CSS/JS. For a deeper guide in Chrome Dev Tools, see 6:27 of Google’s video on improving load performance.

 

7. Use Font-Display: Optional

Fonts add delays when they’re not loaded properly which increases LCP and causes layout shifts. It’s often a tradeoff between FOIT (flash of invisible text) or FOUT (flash of unstyled text).

Foit vs fout
Credit: malthemilthers.com

If you need to ensure text remains visible during webfont load, use font-display: optional which is recommended by Google for optimal performance. Most tools only support “swap” like cache plugins, Elementor, and even dedicated font plugins like OMGF and Swap Google Fonts Display. You can either just use the swap method, or use font-display: optional by editing your font’s CSS and adding the code yourself. The only plugin I know that supports optional is WP FOFT Loader.

/assets/vendor/googleapis/css2?family=Lato:wght@100&display=optional
@font-face {
font-family: "Lato Regular";
font-weight: 300;
font-style: normal;
src: url("fonts/Lato-Regular-BasicLatin.woff2") format("woff2");
font-display: optional;
}
Elementor google fonts swap
Most plugins only support font-display: swap

 

8. Reduce Font Requests And File Sizes

LCP is the load time of your main content which fonts are part of.

Font Optimization 101

  • Use WOFF/WOFF2, not TTF.
  • Consolidate font families, weights, icons.
  • Disable font icons if you’re not using them.
  • Host fonts locally (instead of fonts.gstatic.com).
  • If they load from fonts.gstatic.com, preconnect that domain.
  • Once hosted locally, preload important font files loading above the fold.
  • Inline fonts (some cache plugins do this or use Elementor’s inline experiment).

Local vs third party fonts

 

9. Lazy Render HTML Elements

FlyingPress and LiteSpeed Cache can lazy render HTML elements.

This is similar to lazy loading images but can be done for any element on your website (#comments and #footer are common, just make sure to copy selectors for your own site as shown in the video). It improves LCP by letting browsers focus more on above the fold content.

Lazy render html elements flyingpress

 

10. Preload, Preconnect, Prefetch

Other than prioritizing above the fold images, there may be other files you can prioritize with resource hints. This can be done in most optimization plugins or by adding code to your head.

The “avoid changing critical requests” section of PSI shows resources loaded with a high priority. You should also consider preloading self-hosted fonts and CSS/JS files needed for above the fold content. Just make sure you test your results (in your Waterfall chart) after adding each resource hint. Too many hints or not using them correctly can hurt performance.

Avoid chaining critical requests

Preload – can also be done with above the fold fonts, CSS, JS, and other files types. For example, you could preload the WordPress Block Library stylesheet. Fonts should use the crossorigin attribute. As with all resource hints, test performance after each hint is added.

<link rel="preload' href="/style.css" as="style">
<link rel="preload' href="/script.js" as="script">
<link rel="preload' href="/font.woff2" as="font" crossorigin>

Preconnect – usually only done with CDN URLs (i.e. BunnyCDN) and third-party fonts (i.e. fonts.gstatic.com). Cloudflare doesn’t use a CDN URL and most cache plugins automatically preconnect the CDN URL when you add it to the plugin settings. Since fonts should be hosted locally and CDN URLs are preconnected by cache plugins, there’s usually no need to do this.

<link rel="preconnect" href="/assets/vendor/gstatic" crossorigin>
<link rel="preconnect" href="https://cdn.yourdomain.com" crossorigin>

Prefetch – usually nothing to do here unless you have third-party code loading above the fold, like a social sharing plugin loading at the top of your blog making requests to Facebook. Third-party code should be delayed when it’s loaded below the fold instead of using the prefetch hint.

<link rel="dns-prefetch" href="https://connect.facebook.net">

 

11. Optimize Images

While above the fold images are the most important to optimize largest contentful paint, all images are obviously important. Most of these are recommendations in PageSpeed Insights.

I prefer image CDNs like Cloudflare Mirage + Polish (what I use with Cloudflare Enterprise) or Bunny Optimizer which eliminates the need for image optimization plugins and are automatic.

  • Serve smaller Images to mobileCloudflare’s image resizing and Bunny Optimizer resize images for mobile while other CDNs like RocketCDN do not. Or you can use ShortPixel Adaptive Images. This can improve your mobile LCP score.
  • Properly size images – crop/resize images to their correct dimensions.
  • Compress images – Lighthouse tests images at 85%, so that’s a good number.
  • Specify image dimensions – most cache plugins have a setting to add missing image dimensions. Otherwise, you can manually add a width/height attribute to the image’s HTML which makes the image load faster and prevents layout shifts.
  • Use WebP – faster image format supported by most image CDN/plugins. You could even use a WebP converter to only convert above the fold images if you don’t want to make the full switch yet. If you’re not using WebP, know when to use jpg or png.

Image optimizations

 

12. Use Brotli When Possible

Brotli compresses files to smaller sizes than GZIP. The trick is finding a host that supports it, for example, Rocket.net and Kinsta do. Check with your host and consider this next time you move.

Brotli cpanel

 

13. Increase Cache Expiration Time

Longer cache expirations prevent the server from rebuilding the cache as frequently and improves LCP with better cache hit ratios. Google also suggests this in a YouTube video on LCP.

If using Cloudflare, you can do this under browser cache TTL in the Caching settings. Google recommends 1 year to fix “serve static assets with an efficient cache policy”. This is good for static sites (like my blog) but WooCommerce and dynamic sites should only use about 1 month.

Cloudflare browser cache ttl

 

14. Choose The Right Cache Plugin And Settings

Again, while I try to keep things unbiased, FlyingPress is clearly better at optimizing LCP than WP Rocket and SiteGround Optimizer. Gijo is usually the first to release new features which address core web vitals like delaying JavaScript or adding fetchpriority. Sometimes WP Rocket follows, but other times they don’t add a feature at all. SiteGround Optimizer is far behind both and primarily optimizes for caching instead of core web vitals (with lots of compatibility issues).

WP Rocket has no image optimization, their CDN has no features other than serving files, no documented APO compatibility (still), and way too many lacking features to keep paying for it.

Use FlyingPress or LiteSpeed Cache, not WP Rocket or SiteGround Optimizer.

I have tutorials for nearly every cache plugin.

LCP Optimization SG Optimizer WP Rocket FlyingPress
Preload critical images x x
Exclude leading images x x
Fetchpriority resource hint x x
Remove unused CSS x Inline Separate file
Critical CSS x
Font-display: swap x
Lazy render HTML elements x x
Documented APO compatibility x x
CDN SiteGround CDN StackPath BunnyCDN
Image optimization via CDN x x
Serve small images to mobile via CDN x x

 

15. Enable Signed Exchanges (SXGs) In Cloudflare

Signed Exchanges improve largest contentful paint when people click your links in Google’s search results (through prefetching). Google lists Cloudflare in their documentation and says enabling it can lead to a substantial improvement. This is found under Speed → Optimization.

Cloudflare automatic signed exchanges

 

16. Use Cloudflare Workers For Serverless Rendering

Philip Walton was able to reduce LCP by about 80% using service workers.

Cloudflare has documentation on deploying a static WordPress site which is mainly for developers (which I don’t consider myself one), but I’ll leave it here in case you want to try it.

I’m a blogger, I know my limits :/

 

17. Move Plugin Content, Ads, And Animations Below The Fold

I want to emphasize that large, unoptimized files loading above the fold increases LCP.

Loading Google AdSense in your header, heavy image galleries or animations at the top of content, mega menus, and social sharing plugins at the top of your blog is usually not a good idea. Sure, you may be able to optimize them, but if you can’t and they’re killing your LCP or other scores, try moving them below the fold so they can be delayed or optimized other ways.

 

How do I improve largest contentful paint in WordPress?

LCP can be improved by optimizing above the fold content, eliminating delays, and reducing/optimizing files and TTFB. Since LCP measures the load time of main content in the viewport, there are many factors.

How do I improve largest contentful paint using WP Rocket?

WP Rocket optimizes LCP with features like critical CSS, font-display swap, and removing unused CSS. However, it lacks LCP optimizations like automating the optimization of above the fold images, fetchpriority hints, and serving smaller images to mobile devices. These features have already been added in other cache plugins or their CDNs, not in WP Rocket.

Cheers,
Tom

You Might Also Like:

2 thoughts on “Largest Contentful Paint In WordPress: Advanced Guide To Improving LCP Score”

  1. I’m still having a bit of trouble wrapping my head around LCP but thanks for laying it down, Tom. Love the new look here!

    Reply
    • Chrome Dev Tools Waterfall chart is the best thing to look at. Thanks Malik! There should be a “version 2” coming out by the end of the year with a bunch of updated tutorials, but the main ones like this are “done.”

      Reply

Leave a Comment