Your site loads in 4 seconds? You're losing 30% of visitors before they even see the homepage. Google knows it, and since 2021 it officially measures speed with Core Web Vitals. We, at Meteora Web, have been following businesses since 2017: every millisecond saved on load time translates into revenue. In this pillar guide we take you from the problem – a slow, penalized site – to the practical solution: optimizing LCP, INP, CLS, interpreting Lighthouse and PageSpeed Insights, and taking action on WordPress or any stack.
Understanding Core Web Vitals: what they measure and why they matter
Core Web Vitals are a set of real-user metrics (based on actual user data, not synthetic tests) that Google uses as a ranking signal. They are not optional. If your site doesn't meet them, you lose positions in SERP and, worse, you lose customers. There are three current metrics.
LCP – Largest Contentful Paint
Measures the time it takes for the largest element (image, video, text block) to become visible. Threshold: under 2.5 seconds is “good”. Over 4 seconds is “poor”. LCP is often the main bottleneck: massive images, slow fonts, slow server.
INP – Interaction to Next Paint
Replaces the old FID (First Input Delay). Measures the overall responsiveness of the page: how long from the first click/tap to the next visual update. Threshold: under 200 milliseconds is good. INP suffers when the main thread is blocked by heavy or poorly managed JavaScript.
CLS – Cumulative Layout Shift
Quantifies how much the page “jumps” during loading. Images without dimensions, ads that appear suddenly, fonts that change layout: all cause shifts. Threshold: CLS less than 0.1. In our experience, fixing CLS is often the quickest fix with immediate impact.
Why it pays off: improving Core Web Vitals isn't just SEO – it's user experience. A site loading in 1 second converts twice as much as one loading in 5 seconds. We see this daily in the projects we manage.
Sponsored Protocol
Optimizing LCP: images, fonts and server response
Images: modern formats and compression
The largest image is often the main cause of a high LCP. Concrete solutions:
- Modern formats: WebP and AVIF. Convert all images. One e-commerce client had images of 2-3 MB each: optimizing them to WebP reduced weight by 60% without quality loss.
- Compression: use tools like Squoosh, ShortPixel, or the Imagify plugin for WordPress. No need for maximum compression – level 80% is almost indistinguishable but cuts weight in half.
- Responsive with srcset: load images sized to the actual viewport. Example:
<img src="photo-800.webp" srcset="photo-400.webp 400w, photo-800.webp 800w, photo-1200.webp 1200w" sizes="(max-width: 600px) 400px, 800px" alt="Description"> - Preload key image: if LCP is a hero image, add
<link rel="preload" as="image" href="hero.webp">in the<head>.
Fonts: font-display swap and preload
Fonts loaded from Google Fonts or external servers often block rendering. Golden rule: font-display: swap in the @font-face rule. This way the browser displays text with a fallback font and swaps it as soon as the custom font loads. Example:
@font-face {
font-family: 'MyFont';
src: url('/fonts/myfont.woff2') format('woff2');
font-display: swap;
}
Also, preconnect the font domain: <link rel="preconnect" href="https://fonts.googleapis.com"> and <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>. Subsetting (downloading only the characters you use) further reduces weight.
Server: TTFB and caching
Time To First Byte (TTFB) should be under 200 ms to contribute to a good LCP. How to reduce it:
Sponsored Protocol
- CDN: Cloudflare, BunnyCDN, or your hosting's CDN. Distributes static content from servers close to the user.
- Caching: enable page cache (e.g., Redis, Varnish) and static resource caching with long cache headers.
- Performant hosting: if you're on a shared server with 50 other sites, TTFB will be high. We often recommend managed VPS or optimized hosting for WordPress like Kinsta, WP Engine, or Italian hosting with local servers.
Optimizing INP: reducing main thread blocking
INP measures the page's ability to respond to interactions. A blocked main thread from JavaScript makes the site feel sluggish.
JavaScript: reducing the load
- Code splitting: load only the JS needed for initial interaction. With webpack, Vite, or Laravel Mix it's automatic.
- Defer and async: use
deferfor scripts that don't modify critical DOM;asyncfor independent scripts. - Lazy load widgets: sliders, popups, maps – load them after user interaction.
- Remove unused JS: Chrome DevTools shows “Coverage”; eliminate unused CSS and JS.
Optimized event handlers
Don't use JavaScript for CSS animations – let the browser handle them with transition and animation. For click handling, avoid heavy libraries; vanilla JS is often sufficient.
Web Workers for heavy tasks
If you need to process data or perform calculations, move them to a Web Worker. The main thread stays free to handle user clicks.
Optimizing CLS: zero layout shift
Width/height attributes for images and videos
This is the simplest and most powerful fix. Every <img> must have width and height specified (also via CSS). Example: <img src="photo.jpg" width="800" height="600" alt="...">. Modern CSS aspect-ratio does the same: aspect-ratio: 16/9.
Reserved space for ads and embeds
Ad banners that load late shift the content below. Reserve space with min-height equal to the expected dimensions. If the ad is not shown, the space remains empty.
Sponsored Protocol
Avoid dynamic insertions above the fold
Don't add elements above the fold after initial load (e.g., popups, cookie banners that appear with animations). If necessary, show them with position: fixed – they don't shift the layout.
Lighthouse and PageSpeed Insights: how to use them
Interpreting the report
Lighthouse is a synthetic tool (runs tests from a fixed server). PageSpeed Insights (PSI) combines Lighthouse with field data (CrUX). Don't stop at the green score: look at “Opportunities” and “Diagnostics”. Each opportunity has an estimated savings in seconds – prioritize those with the biggest impact.
Differences between lab and field data
Field data (CrUX) is the truth: it comes from real users. If the lab test scores 90/100 but CrUX shows LCP > 4 seconds, you have a network or caching problem that the synthetic test doesn't detect. We always compare both to decide where to act.
Prioritizing fixes
- First: improve LCP (images, server, fonts)
- Then: reduce JS execution time (INP)
- Finally: eliminate shifts (CLS)
Lazy loading and image criticality
Native lazy loading vs Intersection Observer
Native loading="lazy" is supported by all modern browsers. No JavaScript needed. Example: <img src="photo.jpg" loading="lazy" alt="...">. For legacy support (old browsers) you can use Intersection Observer as a fallback. Important: do not lazy load images above the fold – the LCP image must load immediately.
Effect of lazy loading on metrics
Using lazy loading on images below the fold reduces total weight and improves LCP (because the browser doesn't download everything at once). But applying it to the hero image blocks LCP. Rule: no lazy loading for the main image.
Sponsored Protocol
Critical CSS and rendering path
What is the Critical Rendering Path
The path the browser follows to display the page: HTML → CSSOM → Render Tree → Paint. Every external CSS file blocks rendering. Critical CSS means inlining the CSS needed for above-the-fold content directly in the <head>, and loading the rest asynchronously.
Extracting and inlining critical CSS
You can use tools like Critical (npm), or plugins for WordPress (WP Rocket, Autoptimize, Flying Pages). We prefer automating it with a build tool (e.g., Laravel Mix with plugin).
Tools and automation
npm install critical
npx critical --base . --src index.html --dest css/critical.css --width 1300 --height 900
Then include it inline: <style>...content of critical.css...</style>. Load the rest of the CSS with media="print" onload="this.media='all'".
Optimizing web fonts
font-display: swap, optional, block
swap is the best choice for performance: shows the fallback immediately. optional is even better: if the font doesn't arrive within 100ms, it keeps the fallback permanently. block blocks text until the font loads – terrible for LCP.
Preconnect and preload
Add in the <head>:
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="preload" href="/fonts/myfont.woff2" as="font" type="font/woff2" crossorigin>
Subsetting and woff2 format
Use only woff2 (best compression). Subsetting: discard unused glyphs (e.g., only Latin characters). Google Fonts allows specifying the subset: ?subset=latin,latin-ext. We often self-host fonts to eliminate external calls and have full control over caching.
Sponsored Protocol
Performance on WordPress: plugins and strategies
We've been managing WordPress for almost 10 years. Here's what really works.
Caching
Install a full caching plugin: WP Rocket (premium), Flying Press, or WP Fastest Cache. Enable page cache, object cache (if you have Redis), and minify HTML/CSS/JS.
Image optimization
Imagify, ShortPixel, or WebP Express automatically convert to WebP. Set quality between 70-80% and enable native lazy loading.
Database
Use WP-Optimize or Advanced Database Cleaner to remove revisions, spam, expired transients. A clean database reduces query time.
Recommended and avoidable plugins
- Recommended: WP Rocket, Perfmatters, Asset CleanUp (to disable scripts per page).
- Avoid: heavy page builders (Elementor with many widgets can be slow – optimize with specific caching). Unoptimized slider plugins.
Advice from someone who has managed ERP systems: every plugin is a cost in terms of performance. Evaluate if you really need it. We've seen sites with 50 useless plugins – after reducing to 15, load time dropped by 40%.
In summary — what to do now
- Test your site with PageSpeed Insights. Note field metrics (CrUX) and opportunities.
- Fix LCP first: optimize the hero image (WebP + preload + width/height), reduce TTFB, set font-display swap.
- Reduce JavaScript: remove unnecessary scripts, defer the rest, lazy load widgets.
- Stabilize layout: add dimensions to all images, reserve space for ads.
- Automate Critical CSS and load fonts efficiently.
- If on WordPress: install a performant caching plugin, optimize images, and clean the database.
Every second recovered is an extra customer. We measure it every day. If you want a tailored technical audit, find us in Sciacca – but we work with all of Italy. Start from the data, do it now.