StackForge Guide
March 28, 2026 · tutorial

How to Speed Up WordPress in 2026: Core Web Vitals Playbook

A practical guide to hitting LCP < 2.5s and INP < 200ms on WordPress. Covers hosting, caching, images, and database optimization — in that order.

Providers tested in this article

WordPress performance optimization has a correct order of operations. Most guides start with image compression. That's wrong. You can have perfectly optimized images on a slow server and still fail Core Web Vitals. Here's the sequence that actually works.


Step 1: Fix the Foundation (Hosting)

Before touching a single plugin, check your TTFB. Open DevTools (F12 → Network → reload → click the first HTML request). Look at "Waiting (TTFB)" in the timing breakdown.

If your TTFB is over 600ms: No optimization technique will reliably get you to LCP < 2.5s. You need better hosting or a different server configuration.

Benchmarks by hosting tier:

Hosting typeTypical TTFB (uncached)Can hit LCP < 2.5s?
Managed (Kinsta, WP Engine)300–400msYes, easily
Cloud VPS managed (Cloudways)350–450msYes, with good caching
Quality shared (SiteGround)400–500msYes, with aggressive caching
Budget shared (DreamHost)450–700msMarginal
Truly cheap shared600ms–2sNo

If you're on budget shared hosting and hitting 700ms+ TTFB, move hosts first. Cloudways' $14/mo DigitalOcean plan will cut your TTFB in half versus a typical shared host.


Step 2: Configure Server-Level Caching

WordPress is dynamically generated by default — every page request hits PHP and MySQL. Server-level caching serves pre-built HTML files and eliminates that overhead.

Options by hosting:

  • Kinsta: Uses Nginx FastCGI cache automatically. Zero configuration needed.
  • Cloudways: Varnish cache available. Enable it in the Application Management panel.
  • Self-managed VPS: Install Redis or Nginx FastCGI cache manually. Use our Script Generator to get a working Nginx cache config.

Do not install a caching plugin (W3 Total Cache, WP Rocket) as a substitute for server-level caching. Use it as a complement.


Step 3: Install WP Rocket (or Equivalent)

WP Rocket handles client-side optimization that server caching can't: CSS/JS minification, lazy loading, preloading, and database cleanup.

Configuration that matters:

  1. File Optimization → Minify CSS/JS: Enable both. Test after enabling — some plugins break on minification.
  2. Media → Lazy Load Images: Enable. This alone can knock 1–2 seconds off LCP on image-heavy pages.
  3. Preload → Preload Cache: Enable. Warms cache after it's cleared.
  4. Database → Optimize Tables: Run monthly. A WooCommerce store can accumulate thousands of orphaned rows.

Step 4: Fix Images (The Right Way)

Image optimization is step 4, not step 1. Once it's your turn:

Serve WebP: Convert all images to WebP. In WordPress 6.1+, WebP conversion is built into the media library. Enable it in Settings → Media.

Set explicit dimensions: Every <img> tag should have width and height attributes. Without them, the browser can't reserve layout space, causing CLS (Cumulative Layout Shift) — a Core Web Vitals failure.

Preload your LCP image: The LCP element (usually the hero image) should be preloaded. In your theme's functions.php or via a plugin:

function preload_hero_image() {
    echo '<link rel="preload" as="image" href="/path/to/hero.webp" fetchpriority="high">';
}
add_action('wp_head', 'preload_hero_image', 1);

Serve images from a CDN: Kinsta includes Cloudflare CDN free. Cloudways has BunnyCDN as a paid add-on. For self-managed, use Cloudflare's free tier.


Step 5: Audit and Remove Render-Blocking Resources

Open Chrome DevTools → Lighthouse → run the audit → look for "Eliminate render-blocking resources."

Common culprits:

  • Google Fonts loaded in <head> (swap to font-display: swap or preconnect)
  • jQuery plugins loaded site-wide but used on one page
  • Unused CSS from page builders (Elementor loads its full CSS on every page)

For Elementor: Install the Elementor Optimizer or use the built-in "Improved Asset Loading" experimental feature in Elementor → Settings → Experiments.


Step 6: Database Optimization

WooCommerce in particular creates database bloat: expired transients, draft orders, old sessions, and revision overload.

Run this query monthly (or automate via WP Rocket's database optimizer):

-- Delete expired transients
DELETE FROM wp_options
WHERE option_name LIKE '%_transient_%'
  AND option_name NOT LIKE '%_transient_timeout_%';

-- Delete auto-draft posts older than 30 days
DELETE FROM wp_posts
WHERE post_status = 'auto-draft'
  AND post_modified < DATE_SUB(NOW(), INTERVAL 30 DAY);

After deleting, run OPTIMIZE TABLE wp_options; to reclaim disk space.


Measuring Your Results

Before and after every change, measure:

  1. Google PageSpeed Insights — tests from Google's servers (Lighthouse 10)
  2. WebPageTest — filmstrip view shows exactly what loads when
  3. Chrome DevTools → Performance — flame graph for JavaScript execution time

Target metrics for 2026:

  • LCP < 2.5s (good) / < 1.2s (excellent)
  • INP < 200ms (good) / < 100ms (excellent)
  • CLS < 0.1 (good)
  • TTFB < 800ms (good) / < 200ms (excellent)

Quick Win Checklist

  • Check current TTFB — if > 600ms, fix hosting first
  • Enable server-level caching (FastCGI / Varnish / Redis)
  • Install WP Rocket and configure minification + lazy load
  • Convert images to WebP
  • Preload LCP image with fetchpriority="high"
  • Remove unused plugins (every inactive plugin still loads autoloaders)
  • Schedule monthly database optimization

The correct order matters. Don't compress images on a 700ms TTFB server and wonder why you're still at LCP 3.8s.