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.

In 2019, I moved from SiteGround to Cloudways Vultr HF and posted my results. In 2022, I moved to Rocket.net with Cloudflare Enterprise which landed me a <100ms global TTFB in KeyCDN. They’re the fastest host I’ve used in 12 years and are blowing up in Facebook groups.

If you have a poor TTFB, you need to rethink your hosting/CDN setup since those are the 2 main TTFB factors . After writing bad reviews of SiteGround, Hostinger, Kinsta, and EIG, I think we can agree most hosting reviews are garbage. A good place to get unbiased feedback is the WP Speed Matters Group (run by Gijo from FlyingPress). Rocket.net doesn’t do aggressive marketing so not as many people know about them, but results are all I care about. Hence, a <100ms global TTFB:

Keycdn global ttfb
My KeyCDN report (you can also check my GTmetrix / PSI report or click through my site)

Good hosting plans:

FastComet FastCloud Extra NameHero Turbo Cloud Cloudways Vultr HF (2GB) Servebolt Pro Rocket.net Starter
Type Shared Shared Cloud Cloud Cloud
Server LiteSpeed LiteSpeed Apache + Nginx Apache + Nginx Apache + Nginx
Cores/RAM 6 cores/3GB 3 cores/3GB 1 core/2GB Unmetered 32 cores/128GB
Storage 35GB / SATA Unlimited NVMe 64GB / NVMe 4GB / NVMe 10GB / NVMe
CDN QUIC.cloud QUIC.cloud Cloudflare Enterprise ($5/mo) Cloudflare Enterprise ($299/mo) Cloudflare Enterprise (free)
CDN PoPs 80 80 285 285 285
Full page caching
CDN image optimization via QUIC via QUIC Mirage/Polish Mirage/Polish Mirage/Polish
DNS Use QUIC Use QUIC DNS Made Easy ($5/mo) x Cloudflare
Cache plugin LiteSpeed Cache LiteSpeed Cache x Servebolt plugin x
Object cache Memcached Redis Redis Pro x Redis
PHP processor LiteSpeed LiteSpeed FPM Apache 2 ITK MPM LiteSpeed
Database MySQL MariaDB MariaDB MariaDB MariaDB
Bandwidth or monthly visits 92GB + 100k (est.) 50k (est.) 2TB 1M dynamic requests 50GB + 250k visits/mo
Control panel cPanel cPanel Custom Custom Custom
Email hosting x x x
Major incidents 2022 DDoS attack 2011 2-day node outage None None None
Migrations 3 free 1 free 1 free + $25/site Unlimited free Unlimited free
TrustPilot rating 4.9/5 4.6/5 4.5/5 4.5/5 4.9/5
Monthly price $5.49 (1-3 years) $9.98 (3 years) $30 $99 $25 (1 year)

  • Shared LiteSpeed HostingFastCloud Extra, Turbo Cloud, and ChemiCloud’s WordPress Turbo plan are all shared LiteSpeed hosting with cPanel and good alternatives to SiteGround & Hostinger. NameHero and ChemiCloud have less cores/RAM but use NVMe (faster than SATA), Redis (faster than Memcached), and MariaDB (faster than MySQL). NameHero’s data centers are only in US & EU, and NameHero/ChemiCloud make you sign up for 3 years to get their cheapest intro price (FastComet is 1-3 years). With either of these, you’ll use the free LiteSpeed Cache plugin and QUIC.cloud’s CDN (great setup). For cloud VPS, Scala is a solid host and doesn’t charge for the LiteSpeed license separately like other VPS hosts. Imunify360 is used as a security suite on FastComet, NameHero, and Rocket.net.
  • Cloudways Vultr HF – good starting point for cloud hosting with more storage + bandwidth than Rocket.net, but their Cloudflare Enterprise needs APO and serves too many challenge pages. They were acquired by DigitalOcean who raised prices, and support could be better. Still very fast between Vultr HF, NVMe, Redis Object Cache Pro, and MariaDB. Even without APO, Cloudflare Enterprise is a powerhouse for reducing TTFB with Argo Smart Routing and prioritizing routing. Mirage/Polish optimize images better than most plugins and doesn’t tax your server. Cloudflare Enterprise can also mean 3 less plugins between image, CDN, and security plugins.
  • Servebolt – incredibly fast servers, but Cloudflare Enterprise costs $299/mo via accelerated domains, so you’ll probably just add APO using the Cloudflare plugin. However, this is a disadvantage (specifically for WooCommerce sites) because you don’t get Argo Smart Routing, and Redis is only available on the Business plan and up (Rocket.net includes both). This and low storage are the main cons but they’re much faster than Kinsta + WP Engine. They also have a Servebolt Optimizer plugin.
  • Rocket.net – only host I know that averages a <100ms global TTFB. Both their hosting and Cloudflare Enterprise have better specs. For hosting, you get more CPU cores/RAM, LiteSpeed’s PHP, NVMe, Redis, and MariaDB. For their Cloudflare Enterprise, it’s free with APO, Argo, prioritized routing, Mirage/Polish, Brotli, early hints, and Enterprise WAF. Support is also A+ (talk to Ben Gabler and his team) or watch the interview I did with him. Unlike Kinsta and WP Engine, they don’t limit PHP workers, have a 1GB memory limit, and use Redis Object Cache Pro on their business plan and up with 10x more monthly visits and unlimited free migrations. The main con is only 50GB bandwidth on the Starter plan with 10GB NVMe storage. Search their TrustPilot reviews for “TTFB” or search Facebook Groups for feedback about them. You can get $1 your first month when you checkout using code OMM1

Siteground to rocket. Net
452% LCP improvement

Rocket. Net trustpilot review

Kinsta to rocket. Net migration

Moved to rocket. Net vs siteground

Rocket. Net positive review

Litespeed cache litespeed server

Rocket. Net woocommerce elementor
Cloudflare Enterprise significantly reduces TTFB

Rocket. Net vs cloudways vultr hf trustpilot review

Rocket. Net facebook review 1

Rocket. Net vs kinsta

Kinsta to rocket. Net ttfb redis

Namehero vs siteground feedback

Bad hosting plans (and bad hosts in general):

SiteGround GrowBig Hostinger Business WP Bluehost Choice Plus WP Engine Startup Kinsta Starter
Type Shared Shared Shared Cloud Cloud
Server Apache + Nginx LiteSpeed Apache + Nginx Apache + Nginx Apache + Nginx
Cores/RAM Not listed 2 cores/1.5GB Not listed Not listed 12 cores/8GB
Storage 20GB / SATA 200GB / SATA 40GB / SATA 10GB / SATA 10GB / SATA
CDN Google Cloud QUIC.cloud Cloudflare free Cloudflare free + Polish Cloudflare APO + firewall rules
CDN PoPs 176 80 285 285 285
Full page caching via CDN via QUIC x x
CDN image optimization Very limited via QUIC x Polish only x
DNS Blocked by Google for 4 days Use QUIC Internal Internal Amazon Route 53
Cache plugin SG Optimizer LSC x x x
Object cache Memcached Memcached x Memcached Redis ($100/mo)
PHP processor FastCGI LiteSpeed FastCGI Not listed FastCGI
Database MySQL MySQL MySQL Not listed MySQL
Resource limits CPU limits are common Low resources Low resources Low PHP workers + 25k visits/mo 2 PHP workers + 25k visits/mo
Inodes 400k 600k 50k Unlimited Unlimited
Control panel Site Tools hPanel cPanel User Portal MyKinsta
Email storage 10GB 1GB Adjustable x x
Major incidents Denies issues with TTFB, DNS, CPU, others Scam reports, fake reviews, 2019 breach Claims of hosting terrorist sites 2015 breach None
Migrations $30/site Unlimited (but screws it up) Free on qualified accounts only Paid (quoted) Free on select hosts + 1 free
TrustPilot rating 4.6/5 4.6/5 (fake) 3.7/5 4.5/5 4.2/5
Monthly price $3.99 (1 year) $3.99 (2 years) $5.45 (1 year) $20 (1 year) $29 (1 year)
Renewals $24.99/mo $14.99/mo $19.99/mo $25/mo $29/mo

  • SiteGround – $25/mo for a shared GrowBig plan is a ripoff. Top it off with a poor cache plugin, inferior CDN than Cloudflare APO, CPU limits, and a support team that constantly lies about their issues… means you’re getting ripped off. If your LCP is high, I bet you use SiteGround Optimizer which does a poor job with web vitals, plus they’ve have TTFB issues. Their CDN requires you to use SiteGround’s DNS which was blocked by Google for 4 days. To cover up their mess, they deny everything and use Facebook group admins (who run several groups) to promote SiteGround on their behalf and act like support agents. They have “good reviews” only because of affiliates and legal threats. Check this thread about Hristo’s AMA.
  • Hostinger – only cheap because they lack resources like cores, RAM, and email storage. Everyone gets drawn to their cheap prices and LiteSpeed, but have you read their scam reports and fake reviews? I would never trust them with my site. Support is horrendous and will screw up migrations, suspend your account, and pretty sure they outsource it to an ice cream truck in Lithuania. The CEO admitted to fake reviews, they’re banned from Facebook groups for voting for themselves in polls, and hired brand ambassadors who pretend to be customers. Check this poll.
  • Bluehost – another host that grew from “how to start a blog” affiliates and pays WordPress to be “officially” recommended. Use a shared LiteSpeed host instead.
  • WPX – no redundancy system which already lead to a global outage they blamed on a dead CEO. Ticking time bomb, overpriced shared hosting, and not the fastest WordPress host like Matthew said (but now he lists Kinsta #1)? Marketing gimmick.
  • WP Engine – I reached out to them about their specs, but they don’t give them out. When a host doesn’t list basic things like cores/RAM, I assume it’s not good. From my experience, they’re similar to Kinsta but even worse with pricey overages.
  • Kinsta – great option if you want to go bankrupt with paid add-ons that should be free. Compared to Rocket.net, you get 16x less RAM, 10x less monthly visits, brutal PHP worker limits, and a very low memory limit of 256MB. What are you paying so much for? Slower SATA SSDs, a premium DNS that’s slower than Cloudflare’s, and staging sites that get 1 CPU core? Madness! No wonder their TrustPilot rating sunk.

Avoid siteground

Siteground to cloudways dns issue

Hostinger is the worst

Godaddy mention

Siteground slow ttfb leave

Siteground renewal prices

Hostinger banned from facebook groups

Bluehost hostgator godaddy worst choices

I agree:

Namehero cloudways rocket. Net
NameHero for shared LiteSpeed, Cloudways Vultr HF for cloud, Rocket.net outperforms both

 

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 :)

Cheers,
Tom

You Might Also Like: