Skip to content
tak.tn
← Back to blog
3 min read

Core Web Vitals on Drupal: diagnosis and fixes that work

#seo#performance#drupal

Core Web Vitals are one of the rare subjects where SEO and user experience say exactly the same thing: a slow site loses rankings and visitors. Drupal can be remarkably fast — core’s page cache is excellent — but most Drupal sites I audit leave enormous points on the table. My own old personal site was the perfect example: 58 render-blocking stylesheets for a single page. Here is the method I apply on engagements.

First: measure in the right place

  • Field data wins. Google ranks on real Chrome-user data (CrUX), visible in Search Console (the Core Web Vitals report) and PageSpeed Insights. Local Lighthouse is a diagnostic tool, not the final grade.
  • The three metrics that count: LCP (main element load, < 2.5 s), INP (interaction responsiveness, < 200 ms), CLS (visual stability, < 0.1).
  • Diagnose per template (home, article, listing), not page by page: on a CMS, problems are structural.

LCP: the usual Drupal suspects

  1. Under-exploited caching. Page cache for anonymous users, Dynamic Page Cache for logged-in ones, and above all clean cache tags in your custom blocks — one forgotten #cache max-age: 0 in a block can disable caching for every page that displays it. This is the most expensive and most common performance bug.
  2. CSS/JS aggregation disabled (often “temporarily”, for two years). Core knows how to aggregate and minify: enable it, verify, forget it.
  3. A mistreated LCP image. Use responsive image styles, serve WebP (core does it since Drupal 10), size it correctly — and above all: no lazy loading on the main image. Drupal sets loading="lazy" on content images by default; the hero image must be eager with fetchpriority="high".
  4. Third-party fonts. Self-host, subset, font-display: swap, preload the heading font. A render-blocking fonts.googleapis.com in the <head> is paid for in cash on LCP.
  5. Hosting TTFB. If the HTML takes 800 ms to come out, nothing on the front end will save you. Put an HTTP cache in front of Drupal (Varnish, CDN) for anonymous traffic.

INP: the metric that replaced comfort

INP measures the responsiveness of all interactions. On Drupal, the classic culprits:

  • The library pile-up: jQuery + plugins from another era + three trackers. Every third-party script is a tax on the main thread — marketing’s “temporary” tag manager first among them.
  • Heavy handlers attached to the whole document. once() and event delegation exist for this.
  • The structural remedy: ship less JavaScript. Drupal’s libraries system allows per-component loading — serve the carousel’s JS only where there is a carousel.

CLS: stability is discipline

  • Explicit dimensions on all images and iframes (width/height or aspect-ratio) — Drupal’s image styles provide them; do not strip them in the theme.
  • Reserve space for dynamic zones: ads, embeds, consent banners (the cookie banner that pushes the whole page down is a classic).
  • Fonts with metric fallbacks (size-adjust) to avoid the swap jump.

The exit checklist

In the order I handle them in an audit: cache tags and page cache verified → aggregation enabled → LCP image eager + WebP + sized → fonts self-hosted and preloaded → third-party JS inventory (remove before optimising) → dimensions everywhere → re-measure CrUX at 28 days (the field report is a rolling average: patience is part of the method).

Nothing exotic: discipline, applied in the right order. Which is precisely what a technical SEO audit delivers — the quantified diagnosis, and the fixes implemented.

A Drupal project or a technical SEO challenge?

Let's talk. Reply within one business day, no strings attached.

Get in touch