Core Web Vitals for WordPress: Fixing LCP Without a Plugin Pile
Six caching plugins will not save a theme that ships 400KB of render-blocking CSS. A pragmatic path to sub-2s LCP on real hosting.
The plugin trap
The instinct when Lighthouse turns red is to install something. Three optimisation plugins later the site is slower, harder to debug and one update away from a white screen.
Measure the right thing
LCP is almost always one of three elements: the hero image, an H1 inside a webfont, or a slider. Find yours before touching anything.
new PerformanceObserver((list) => {
const entry = list.getEntries().at(-1);
console.log(class="text-code-string">"LCP element:", entry.element, entry.startTime);
}).observe({ type: class="text-code-string">"largest-contentful-paint", buffered: true });Fix the hero image
Serve AVIF with a WebP fallback, set explicit dimensions, and preload it. Never lazy-load the LCP image — that is the most common self-inflicted regression on WordPress.
<link rel=class="text-code-string">"preload" as=class="text-code-string">"image" href=class="text-code-string">"/hero.avif" fetchpriority=class="text-code-string">"high">Kill render-blocking CSS
Inline the critical above-the-fold rules, defer the rest. On most themes this alone moves LCP by 600–900ms.
Fonts
font-display: swap plus a self-hosted subset. Third-party font CDNs add a DNS lookup, a TLS handshake and a privacy question you do not need.
Server side still matters
TTFB is the floor your LCP sits on. Object caching with Redis and PHP 8.3 on a tuned VPS routinely halves it versus shared hosting.
Paj Digital Labs
The engineering journal of Paj Digital Solutions — hosting, server infrastructure and web engineering, written by the people who run the servers.