15 Easy Ways To Improve First Contentful Paint In WordPress (Core Web Vitals Item)

This is a simple (yet in-depth) guide on improving first contentful paint in WordPress.

First contentful paint (FCP) is the point when users see anything on your site (very similar to LCP where users see your largest image or text block in the viewport). Anything before that (including TTFB, DNS lookups, as well as the first content shown) is part of both FCP and LCP.

Fcp vs lcp

The Waterfall chart in WebPageTest shows which files load in your FCP time (test your site then click the Waterfall image). In the example below, all files loading in green are part of FCP.

First contentful paint

The first request is usually the longest and includes factors like TTFB, DNS, and SSL. The other requests are related to whatever files load first which can be CSS, JavaScript, fonts, and images.

Pay special attention to files loading in the viewport: preloading images/fonts, avoiding bloated headers created by page builders (by hard coding them in CSS), and pushing plugins + third-party code below the fold can help. Aside from reducing the size of files loading in your viewport, using a performant setup (hosting, theme, plugins, CDN) are two big FCP/LCP factors.

First Contentful Paint Score
0–1.8s Good
1.8–3s Needs Improvement
Over 3s Poor


1. Aim For A <100ms TTFB

TTFB is 40% of LCP, which means it’s also a big part of FCP. The 2 biggest TTFB factors are:

  • Hosting
  • CDN, ideally with a large network (PoPs) and full page caching

I always recommend Rocket.net with their Cloudflare Enterprise who averages a TTFB of <100ms globally which you can test in KeyCDN (or click through my site since I’m using them).

Keycdn global ttfb

Here are the specs if you want to do your research:

SiteGround Kinsta WPX Cloudways Vultr High Frequency Rocket.net
Hosting type Shared Cloud Shared Cloud Private cloud
CPU cores + RAM Not listed 12 cores + 8GB Not listed 1 core + 1GB 32 cores + 128GB
Storage (GB) 40 10 15 32 10
Object cache Memcached Redis ($100/mo) x Redis (Pro) Redis (Pro)
Server Apache + Nginx Nginx LiteSpeed Apache Apache + Nginx
PHP processing FastCGI FastCGI FastCGI PHP-FPM LiteSpeed
Bandwidth (or monthly visits) 5TB 25k visits/mo 200GB 1TB 50GB + 250k visits/mo
CDN SiteGround CDN Cloudflare Enterprise QUIC.cloud or XDN Cloudflare Enterprise Cloudflare Enterprise
CDN PoPs 14 270 73 270 270
Full page caching Coming soon
Argo smart routing x x x
Load balancing x x x
Image optimization Limited x
Compression Brotli Brotli Brotli GZIP Brotli
CDN price Freemium Free $.01 – $.04/GB $5/mo Free
CPU limits Common Low PHP workers At their discretion Average None
Cache plugin SG Optimizer x LSC or W3TC Breeze x
Email hosting x Very limited x x
Major incidents Google blocked DNS for 4 days None Worldwide outage None None
Free migration $30/site Unlimited free 5-35 sites free 1 free Unlimited free
Renewals Yearly (high) Monthly Monthly Monthly Monthly
TrustPilot rating 4.6/5 4.4/5 4.9/5 4.6/5 4.9/5
Price $3-8/mo (1 year) then $15-40/mo $29/mo (yearly) $20.83 (yearly) $18/mo (with CF Enterprise) $25/mo (yearly)

I’ve written plenty of bad reviews on SiteGround, Hostinger, Kinsta, Bluehost, GoDaddy, and “mainstream hosts” who are only popular because of marketing, but have less CPU cores/RAM, slower SATA SSDs, low CPU and PHP worker limits, and are mostly overglorified shared hosting.

Cloudways and Scala Hosting are 2 other solid cloud hosts, or RunCloud/GridPane for more DIY. If you absolutely must use shared hosting because of a tight budget, at least use someone who uses LiteSpeed like NameHero or ChemiCloud. Both use NVMe SSDs with more CPU/RAM than other LiteSpeed hosts like Hostinger. Not only is LiteSpeed faster than Apache/Nginx, but it can handle more traffic, is more efficient regarding CPU usage, and you’ll use LiteSpeed Cache with QUIC.cloud. Rocket.net is still faster – but that is arguably the fastest setup if you’re on a budget.

Rocket. Net trustpilot reviewKinsta to rocket. Net migrationMoved to rocket. Net vs sitegroundRocket. Net positive review

Rocket. Net vs cloudways vultr hf trustpilot reviewRocket. Net facebook review 1Rocket. Net vs kinstaKinsta to rocket. Net ttfb redis

Rocket. Net woocommerce elementor

Lcp siteground slow ttfb
Rocket.net with FlyingPress + Perfmatters (and GeneratePress theme) is my current setup = 🔥
Namehero cloudways rocket. Net
NameHero is good for shared, Cloudways Vultr HF for cloud, Rocket.net outperforms both

A few notes about Rocket.net:

  • Here’s a Facebook thread if you’re still not sure.
  • You get your first month for $1 when you create an account.
  • Support is the best I’ve used (by far) and does free migrations.
  • Cloudflare Enterprise is automatically setup (no need to do anything).
  • The only “tweaks” I did were PHP 8 and requesting Redis Object Cache Pro.
  • There are no PHP workers limits and 10-25x more monthly visits than Kinsta.
  • You can see other people who improved TTFB in Rocket’s TrustPilot reviews.
  • It’s owned by Ben Gabler who has extensive experience with hosting + CDNs.
  • Here’s an interview I did with Ben where he answers several helpful questions.
  • Test your before & after results and I also suggest using the WP Hosting Benchmarks plugin (here are my results, my GTmetrix report, and all my URLs pass core web vitals).


2. Reduce CSS + JavaScript Files

Are CSS/JS files part of FCP in your waterfall chart? You can also use the coverage report in Chrome Dev Tools to see your largest files:

Css javascript chrome dev tools

Themes, plugins, and third-party code are usually the biggest culprits. After that, you can further reduce files through the “remove unused CSS” setting in FlyingPress or Perfmatters (faster than WP Rocket’s setting), delaying JavaScript, and replacing plugins. For example, I replaced wpDiscuz with native comments and started using Gutenberg for galleries + tables.

  • Minify CSS/JS.
  • Avoid Elementor, Divi, Avada.
  • If using them, code your header/sidebar in CSS.
  • If using them, activate their performance settings.
  • Elementor can host fonts locally and preload them.
  • Don’t overdo third-party tracking tools, or delay them.
  • Avoid jQuery-dependent plugins (check Perfmatters for this).
  • Use a smaller GA tracking code with Perfmatters or Flying Analytics.
  • Disable WooCommerce scripts/styles and non-eCommerce content.
  • The “remove unused CSS” setting is better in FlyingPress/Perfmatters.
  • Use Perfmatters’ script manager to unload CSS/JS on pages they’re not used.


3. Use Local Fonts, Preload Them, And Use “Swap”

Fonts loading in your first contentful paint time? No problem…

Use Local Fonts – check your Waterfall chart to make sure fonts load from your domain, not fonts.gstatic.com or use.fontawesome.com. If they do, there are several tools to host them locally: several cache plugins can do this (but not WP Rocket), Perfmatters, OMGF, Elementor, Transfonter, etc. Also use woff or better, woff2 which are faster than alternative formats like .ttf. Finally, only use 1 font without loading too many font weights/icons (obvious but still common).

Local vs third party fonts

Preload Fonts – fonts loading above the fold or those in CSS files should be preloaded. There’s no magic tool to learn which fonts to preload, so this requires testing them in a Waterfall chart (preloading too many fonts or preloading fonts not being used can result in a negative impact).

Preload fonts 2

Use Font-Display: Swap – if you need to ensure text remains visible during webfont load, PSI tells you which fonts are causing FOIT (flash of invisible text). Basically, you want to locate that file using String Locator, then add font-display: swap to the @font-face. Some plugins may also be able to do this: Elementor, Perfmatters, FlyingPress, WP Rocket, Swap Google Fonts Display.

@font-face {
font-family: "Lato Regular";
font-weight: 300;
font-style: normal;
src: url("fonts/Lato-Regular-BasicLatin.woff2") format("woff2");
font-display: swap;


4. Preload Viewport Images And Exclude From Lazy Load

Since viewport images should be loaded with high priority, they should be preloaded and excluded from lazy load. Again, FlyingPress/Perfmatters are more effective than WP Rocket.

Above the fold images
Optimizing viewport images is a great way to improve FCP (I have 3 on my pages/posts)

Both can preload critical images where you set the number of images that usually load in the viewport (i.e. 2-3), then they will be automatically excluded from lazy load while preloaded. With WP Rocket, you need to follow an 8-step process just to specify the number of images to exclude from lazy load. Then you need to preload them individually (with code or a plugin like Pre* Party Resource Hints) which is a pain since usually, each page has unique viewport images.

Preload critical images flyingpress

If you have background images loading in the viewport, they’re treated differently, but you’ll want to exclude those from lazy load as well. Cache plugins and page builders usually have documentation on how to do it, for example, some plugins have a “skip-lazy” class you can add.


5. Avoid Page Builders For Headers

Your header/menu is part of the viewport and one of the first things people see.

Creating these with a page builder adds a lot of unnecessary code. So if you insist on using a page builder, code these in CSS (or hire a developer to do this). When I was trying to remove Elementor, I hired WP Johnny and this was the first thing he did which made a huge difference. And while we’re on the topic, stay clear of hamburger menus and other bloated menu plugins.

Wp johnny hardcode header footer service
This important enough that WP Johnny offers it as a $1000 service


6. Defer JavaScript

Eliminating render-blocking resources is the first thing Google recommends to improve first contentful paint, which usually means deferring JavaScript.

If your site breaks, you’ll need to exclude problematic JS files from being deferred. And if you still don’t see good results, try installing Async JavaScript and click “apply defer” in the settings.

Eliminate render blocking resources defer


7. Use Full Page Caching

In Cloudflare’s test, APO improved first contentful paint by around 5% for desktop/mobile.

Of course, there are other options if you don’t want to pay $5/mo for APO: QUIC.cloud’s CDN, Super Page Cache plugin, and Rocket.net’s Cloudflare Enterprise all include full page caching.

Apo impact on first contentful paint


8. Avoid Loading Plugins/Scripts In The Viewport

Since the viewport is high priority, consider moving heavy plugins/scripts down on the page.

Ads, social sharing buttons, and other files can be pushed down below the fold so they won’t load in the viewport. And, they can usually be delayed which can further improve web vitals.

Perfmatters delay javascript


9. Use A Performant DNS/CDN

Going back to your Waterfall chart, DNS lookup time is part of that long first request, and CDNs are also one of the best ways to improve TTFB.

Cloudflare’s DNS is my go-to which performs well on cdnperf.com (just sign up and change nameservers). If using QUIC.cloud, their DNS seems to perform well. But if you registered your domain with someone like GoDaddy or NameCheap, you’re using their DNS by default which is usually slow. And because DNS speed is part of TTFB, you’ll want to move it from your registrar.

Cloudflare dns

While the best CDN is debatable, there’s no arguing Cloudflare Enterprise, QUIC.cloud (for LiteSpeed), and BunnyCDN are 3 solid options. Cloudflare has a massive network of 270+ locations with extensive speed/security features. QUIC.cloud’s CDN is newer but still has 75+ PoPs with powerful CSS/image optimizations when used with LiteSpeed Cache (but use the paid plan since the free version only uses 6 PoPs). BunnyCDN is another one of my favorites.

Cloudflare settings that can improve FCP include: Signed Exchanges, TCP Turbo, TLS settings, APO, using Workers for serverless rendering, and Brotli (although your host must support this).


10. Use Multiple Caching Layers

Did you know there are 6 different caching layers?

You might know 4 of them: browser cache (done by your cache plugin), CDN cache (done by your CDN), full page cache (done by your CDN), and HTTP accelerators like Varnish/FastCGI (done through your host). There are 2 other important caching types you may not know about:

  • Object Cache – database cache. It’s hard to beat Redis which is more efficient than Memcached, especially Redis Object Cache Pro (included with Rocket.net and Cloudways). Check your host’s documentation/support on how to add it. Rocket.net requires you to install WP Redis, Cloudways involves activating the Redis add-on in their dashboard, or it’s found under PHP Extensions in cPanel.
  • OPcache – compiles PHP scripts in memory and helps reduce CPU usage. Setting this up is unique for each host but in cPanel, it’s also found under PHP Extensions.

Opcache memcached redis


11. Generate Critical CSS And Inline It

Some plugins like WP Rocket generate critical CSS and inline it for you.

Otherwise, you can also use a free critical CSS generator tool which prevents FOUC (flash of unstyled text). The next step would be to inline it. Because the browser won’t have to wait for the CSS, it can start rendering your page sooner which will also improve first contentful paint.

Elementor regenerate critical css
If you make CSS changes, make sure to regenerate to keep critical CSS current


12. Delay JavaScript

Delaying JavaScript can improve both your largest and first contentful paint.

Several cache plugins do this (FlyingPress, Perfmatters, Flying Scripts, WP Rocket). Just make sure you read the documentation and view common scripts to delay. You can even delay entire plugins when they load below the fold, such as third-party comments or social sharing plugins.

How can i improve first contentful paint


13. Fix Errors In Your Waterfall Chart

Sounds obvious, but you’d be surprised how many websites have red errors (which probably means you’re loading something that’s not being used, therefore creating a canceled request). Errors can often create the largest requests on your site, so you’ll want to fix them immediately.

Gtmetrix canceled errors 1


14. Set A Longer Cache Expiration

Serving static assets with an efficient cache policy is an easy one to fix. Check your hosting account to see if there’s a setting. For example in Cloudways, it’s static cache expiry. Google wants a cache expiration of 365 days, but WooCommerce sites should generally use 1 month.

Nginx static cache expiry


15. Test Cloudflare’s Rocket Loader

Rocket Loader defers JavaScript and can improve your site’s first contentful paint. However, it can also break your site, so use with caution. I personally prefer to keep Rocket Loader disabled.

Cloudflare rocket loader


Retest Your First Contentful Paint

PageSpeed Insights can take 28 days to update, so use SpeedVitals which uses Lighthouse.

Speedvitals omm

Omm pagespeed insights


Frequently Asked Questions

What is first contentful paint?

First contentful paint (FCP) measures the point when users see anything on your website. Anything that loads before that (including TTFB, DNS lookup time, and SSL) are part of FCP.

How do I improve first contentful paint in WordPress?

Reducing files loading in the viewport and ensuring a fast setup (hosting, CDN, theme, cache plugin) are two ways to improve first contentful paint. You can also preload fonts/images, defer and delay JavaScript, and avoid using page builders for headers.

Which WordPress plugins improve first contentful paint?

FlyingPress is better at optimizing first contentful paint than WP Rocket since it preloads images, hosts fonts locally, has a faster CDN, and is more effective at removing unused CSS.

How do I improve first contentful paint in Elementor?

Elementor optimizes first contentful paint with Experiments settings and hosting fonts locally while preloading them with font-display: swap. However, Elementor adds extra code compared to other lightweight options. Therefore, Elementor is NOT good for FCP.

Feel free to ask me any questions in the comments. Hope this helped :)


You Might Also Like:

Leave a Comment