How to Improve Core Web Vitals on WordPress (Step-by-Step)
Fix Core Web Vitals on WordPress with this practical guide. Learn the best plugins, hosting choices, and optimization techniques for LCP, INP, and CLS.
WordPress powers over 40% of the web, but out of the box, it’s not optimized for Core Web Vitals. Themes load unnecessary CSS, plugins add JavaScript bloat, and images are rarely optimized.
This guide shows you exactly how to fix Core Web Vitals on WordPress—prioritized by impact, with specific plugin recommendations and code snippets.
Start With Measurement
Before optimizing, establish your baseline:
1. Check Your Current Scores
PageSpeed Insights (most important):
- Go to PageSpeed Insights
- Enter your homepage URL
- Check the Field Data section (real user data)
- Note which metrics are failing: LCP, INP, or CLS
Search Console:
- Go to Search Console → Core Web Vitals
- Check the Mobile report
- Identify which page types are affected
2. Identify Your Worst Pages
Common problem areas on WordPress:
- Homepage: Often has sliders, multiple images, and heavy scripts
- Blog posts: May have large featured images and social embeds
- WooCommerce product pages: Dynamic content, reviews, related products
- Archive pages: Multiple images loading at once
Focus on fixing your highest-traffic pages first.
WordPress LCP Problems (And How to Fix Them)
LCP (Largest Contentful Paint) measures how quickly your main content loads. On WordPress, LCP is usually either:
- The featured/hero image
- A large text block (if no images above the fold)
Problem 1: Unoptimized Images
The issue: WordPress serves original image sizes by default, often in PNG or JPEG format.
The fix:
Option A: Use a plugin (easiest)
Install ShortPixel or Imagify:
- Install and activate the plugin
- Enable WebP conversion
- Bulk optimize existing images
- Enable “Resize large images” to max 2560px
Option B: Code-based (more control)
Add to your theme’s functions.php:
// Enable WebP support
add_filter('upload_mimes', function($mimes) {
$mimes['webp'] = 'image/webp';
return $mimes;
});
// Add image dimensions to content images
add_filter('the_content', function($content) {
return preg_replace_callback('/<img[^>]+>/i', function($match) {
$img = $match[0];
if (strpos($img, 'width=') === false) {
// Add loading="lazy" for below-fold images
if (strpos($img, 'loading=') === false) {
$img = str_replace('<img', '<img loading="lazy"', $img);
}
}
return $img;
}, $content);
});
Problem 2: Hero Image Not Preloaded
The issue: The LCP image loads after CSS and JS, causing delays.
The fix: Preload your hero image in the <head>:
// Add to functions.php
add_action('wp_head', function() {
if (is_front_page()) {
echo '<link rel="preload" as="image" href="' . get_template_directory_uri() . '/images/hero.webp">';
}
}, 1);
Or use a plugin like Perfmatters which has a preload images feature.
Problem 3: Slow Server Response (TTFB)
The issue: Cheap shared hosting often has TTFB >1 second.
The fix:
Caching (essential):
- Install WP Super Cache (free) or WP Rocket (paid)
- Enable page caching
- Enable browser caching
Better hosting (if caching isn’t enough):
- Budget: Cloudways, SiteGround
- Performance: Kinsta, WP Engine, Flywheel
- Value: Hostinger VPS
Target: TTFB under 600ms (ideally under 200ms)
Problem 4: Render-Blocking Resources
The issue: WordPress themes and plugins load CSS and JS in the <head>, blocking rendering.
The fix:
Using WP Rocket:
- Go to Settings → WP Rocket → File Optimization
- Enable “Optimize CSS Delivery”
- Enable “Load JavaScript Deferred”
Using free plugins:
- Autoptimize: Combine and minify CSS/JS
- Async JavaScript: Defer non-critical scripts
Manual approach (functions.php):
// Defer non-critical scripts
add_filter('script_loader_tag', function($tag, $handle) {
$defer_scripts = ['jquery-migrate', 'comment-reply', 'wp-embed'];
if (in_array($handle, $defer_scripts)) {
return str_replace(' src', ' defer src', $tag);
}
return $tag;
}, 10, 2);
WordPress INP Problems (And How to Fix Them)
INP (Interaction to Next Paint) measures responsiveness. WordPress sites often struggle because:
- Too many plugins adding JavaScript
- jQuery dependency chains
- Third-party scripts (ads, analytics, chat widgets)
Problem 1: Plugin JavaScript Bloat
The issue: Each plugin adds its own JS, even on pages where it’s not needed.
The fix:
Audit your plugins:
- Deactivate all plugins
- Test Core Web Vitals
- Reactivate one by one, testing each time
- Remove or replace heavy offenders
Conditionally load scripts with Asset CleanUp or Perfmatters:
- Disable Contact Form 7 scripts on non-contact pages
- Disable WooCommerce scripts on blog posts
- Disable slider scripts on pages without sliders
Problem 2: Third-Party Script Overload
The issue: Chat widgets, analytics, and social scripts block the main thread.
The fix:
Delay third-party scripts until user interaction:
// Add to functions.php - delay scripts until user interacts
add_action('wp_footer', function() {
?>
<script>
const loadScriptsOnInteraction = () => {
// Load chat widget
const chatScript = document.createElement('script');
chatScript.src = 'https://chat-widget.example.com/widget.js';
document.body.appendChild(chatScript);
// Remove listeners after first interaction
['mouseover', 'touchstart', 'scroll', 'keydown'].forEach(event => {
window.removeEventListener(event, loadScriptsOnInteraction);
});
};
['mouseover', 'touchstart', 'scroll', 'keydown'].forEach(event => {
window.addEventListener(event, loadScriptsOnInteraction, { once: true, passive: true });
});
</script>
<?php
}, 99);
Or use Flying Scripts plugin: Delays scripts until user interaction, no code needed.
Problem 3: jQuery Dependency
The issue: Many WordPress sites still rely on jQuery, which adds ~90KB+ and blocks rendering.
The fix:
If your theme doesn’t require jQuery:
// Remove jQuery (only if your theme/plugins don't need it!)
add_action('wp_enqueue_scripts', function() {
if (!is_admin()) {
wp_deregister_script('jquery');
}
});
Safer approach: Use jQuery Migrate Helper plugin to identify what’s using jQuery, then update or replace those components.
WordPress CLS Problems (And How to Fix Them)
CLS (Cumulative Layout Shift) measures visual stability. WordPress CLS issues usually come from:
- Images without dimensions
- Web fonts loading late
- Ads and embeds
- Cookie banners
Problem 1: Images Without Dimensions
The issue: WordPress 5.5+ adds dimensions automatically, but older content and some themes don’t.
The fix:
WordPress should handle this automatically for images added through the editor. For theme images:
// Ensure featured images have dimensions
add_filter('post_thumbnail_html', function($html) {
if (strpos($html, 'width=') === false) {
// Add default dimensions
$html = str_replace('<img', '<img width="1200" height="630"', $html);
}
return $html;
});
Problem 2: Web Font Flash (FOUT/FOIT)
The issue: Custom fonts load after system fonts, causing text to resize/reflow.
The fix:
Preload your fonts:
add_action('wp_head', function() {
echo '<link rel="preload" href="' . get_template_directory_uri() . '/fonts/main-font.woff2" as="font" type="font/woff2" crossorigin>';
}, 1);
Use font-display: swap in your CSS:
@font-face {
font-family: 'YourFont';
src: url('font.woff2') format('woff2');
font-display: swap;
}
Or use system fonts for maximum performance (no flash at all):
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;
}
Problem 3: Ads and Embeds Without Reserved Space
The issue: Ads load after the page renders, pushing content down.
The fix:
Reserve space with CSS:
/* Reserve space for common ad sizes */
.ad-container-leaderboard {
min-height: 90px;
}
.ad-container-rectangle {
min-height: 250px;
}
/* YouTube embeds */
.youtube-embed {
aspect-ratio: 16 / 9;
width: 100%;
}
Problem 4: Cookie Banners Shifting Content
The issue: Cookie consent banners that appear at the top push content down.
The fix: Use bottom-positioned or overlay banners:
.cookie-banner {
position: fixed;
bottom: 0;
left: 0;
right: 0;
/* Not top! */
}
Most cookie plugins (CookieYes, Complianz) have this option in settings.
Recommended WordPress Performance Stack
After optimizing hundreds of WordPress sites, here’s the stack that consistently delivers good Core Web Vitals:
Hosting
- Budget: SiteGround or Cloudways ($10-30/mo)
- Performance: Kinsta or WP Engine ($30-50/mo)
Essential Plugins (Free Stack)
- WP Super Cache - Page caching
- Autoptimize - CSS/JS optimization
- ShortPixel - Image optimization
- Asset CleanUp Lite - Remove unused scripts per page
Premium Stack (Best Results)
- WP Rocket ($59/yr) - All-in-one caching and optimization
- ShortPixel or Imagify - Image optimization
- Perfmatters ($24.95/yr) - Script management and preloading
Theme Choice Matters
Heavy themes are the #1 cause of WordPress performance issues. Avoid:
- Multi-purpose themes with dozens of features
- Themes bundled with page builders
- Themes from ThemeForest (usually bloated)
Good choices:
- GeneratePress - Lightweight, flexible
- Kadence - Good balance of features and speed
- Astra - Popular, reasonably light
- Starter theme - Build only what you need
What If You Can’t Reach “Good” Everywhere?
Sometimes, despite your best efforts, certain pages won’t pass Core Web Vitals—especially on complex WooCommerce stores or ad-heavy sites.
Prioritize:
- Homepage and main landing pages
- High-traffic pages
- Pages that rank well (protect them)
Accept tradeoffs:
- Ad revenue vs. INP score
- Rich features vs. LCP speed
- Conversion tools vs. CLS stability
Document decisions: Know why certain pages fail and what the business tradeoff is.
Frequently Asked Questions
What’s the best WordPress plugin for Core Web Vitals?
There’s no single “best” plugin—it depends on your setup. For most sites, WP Rocket (paid) or the combination of WP Super Cache + Autoptimize + ShortPixel (free) delivers good results.
Should I change themes to fix Core Web Vitals?
If your theme is fundamentally heavy and you can’t optimize it, switching themes can be the fastest path to significant improvements. GeneratePress and Kadence are popular lightweight choices.
How do I know if a plugin is hurting my Core Web Vitals?
Deactivate plugins one by one while monitoring PageSpeed Insights. Or use the “Coverage” tab in Chrome DevTools to see which scripts are adding the most unused code.
My WooCommerce store fails Core Web Vitals. What should I do?
WooCommerce is complex. Focus on: (1) product page image optimization, (2) lazy loading product images on archive pages, (3) deferring cart/checkout scripts on non-commerce pages, (4) quality hosting with object caching.
Next Steps
Run an audit to identify your specific issues:
Tags:
Share this article:
Ready to improve your SEO?
Get a free SEO audit and see exactly what needs fixing on your site
Start Free Audit