Category: Speed and performance

  • Core Web Vitals for WordPress: LCP, INP and CLS

    Core Web Vitals for WordPress: LCP, INP and CLS

    Contents

    1. 01
      Work out which metric is failing

      The short answerHow it actually worksWhy it mattersWhat good looks like

    2. 02
      Fix the one that is actually failingWhat to do about it
    3. 03
      Avoid the traps

      Common misconceptionsWhat this does not solve

    The short answer

    Three metrics make up Core Web Vitals, and each has its own threshold:

    LCP · Loading

    How long the biggest visible element takes to render.

    INP · Interactivity

    How long the browser takes to respond, start to finish, to anything a visitor clicks, taps or types into.

    CLS · Visual stability

    Whether content jumps around while the page is still loading.

    Not Core Web Vitals

    Time to First Byte, First Contentful Paint and Total Blocking Time show up in the same reports and get talked about in the same breath, but none of the three is a Core Web Vital. They are diagnostic metrics that help explain why LCP, INP or CLS is failing. Treat them as supporting evidence, not as a fourth or fifth vital to chase.

    How it actually works

    Largest Contentful Paint

    The LCP element is whichever single thing on the page is biggest by rendered area: usually a hero image, a video poster frame, a CSS background image or a large block of text. Google’s own measurement includes any redirect delay, connection time and server response time before that element can even start rendering, which is why a slow WordPress LCP is usually a hosting and Time to First Byte problem before it is an image-weight problem. Fix the server response first, or the image work does very little.

    A common WordPress misconfiguration works against the reader here directly: lazy-loading the LCP element itself. Lazy-loading defers an image until it is about to enter the viewport, and a hero image is in the viewport from the first paint, so telling it to lazy-load delays the exact element the metric is timing. Preload it instead.

    See the usual reasons a WordPress site loads slowly for the fuller list of causes behind a slow server response.

    Verify

    Confirm which element PageSpeed Insights or Search Console names as the LCP element for the page, then check whether it is set to lazy-load. If it is, that alone can explain a poor score with no other cause present.

    Interaction to Next Paint

    Interaction to Next Paint replaced First Input Delay on 12 March 2024. The two measure different things.

    Before 12 March 2024

    First Input Delay

    Only timed the delay before the browser started processing the very first interaction.

    Current

    Interaction to Next Paint

    Times the full latency, start to finish, of the browser’s response to every interaction on the page, and reports the worst one observed.

    On WordPress, that number is driven almost entirely by the cumulative JavaScript weight of the plugin stack: page builders, sliders, chat widgets, analytics tags and ad scripts all queue work on the same main thread a click has to wait behind.

    Verify

    Check whether a site that passed comfortably under First Input Delay now fails under Interaction to Next Paint with no code change at all. That gap is the clearest sign the two metrics measure different things, not that the site got slower.

    Cumulative Layout Shift

    The scoring formula is impact times distance: how much of the visible screen moved, multiplied by how far it moved. Two small, unrelated shifts add up the same way one big one does.

    On WordPress, the usual causes are missing width and height on images, a web font swap that resizes text after the page has already rendered, and ads, cookie banners or other content injected late into the page.

    Verify

    Reload the page and watch the first two seconds for anything visibly jumping, a button moving as an ad loads in above it, or text reflowing as a font swaps in.

    Why it matters for a WordPress site

    Google Search Central’s own wording on this is worth quoting directly rather than summarizing:

    “Google Search always seeks to show the most relevant content, even if the page experience is sub-par… Having a great page experience can contribute to success in Search, in such cases.”

    “Beyond Core Web Vitals, other page experience aspects don’t directly help your website rank higher in search results.”

    Source: Google Search Central, page experience

    Read plainly, that makes Core Web Vitals a contributing signal among many, not a dominant one. Relevant content that scores poorly on Core Web Vitals can still outrank thin content that scores well.

    What good looks like

    The same three thresholds, restated as the number that gets checked: LCP at 2.5 seconds or less, CLS at 0.1 or less, and INP at 200 milliseconds or less. Google scores each one at the 75th percentile of real visits, segmented separately for mobile and desktop, so a site can pass on desktop and fail on mobile with nothing else different.

    Two different reports can disagree, and it helps to know why before trusting either one on its own.

    Field data

    Chrome User Experience Report

    The data Search Console’s Core Web Vitals report is built on. Reflects real visits from real devices and connections over a rolling window.

    Lab test

    Lighthouse in PageSpeed Insights

    One simulated visit, on one simulated connection, at one moment.

    A site can score well in that single lab run and still fail in the field report, because the field data carries the slow connections and low-end phones the lab test never simulates.

    Server response time also depends on infrastructure the reader is already paying for.

    What to do about it

    A core web vitals fix starts with the diagnosis above, not with a plugin. Each metric has its own fix, and none of the three overlaps much with the others.

    For LCP

    Check Time to First Byte first. Managed WordPress hosting and an edge cache (a Cloudflare-style integration in front of the site) address server response time directly. Once that is solid, move to the hero image itself: serve it in a modern format such as WebP, and preload it rather than lazy-loading it.

    For INP

    Audit the plugin stack for scripts running on every page load that only need to run on one or two. A slider script loading on a page with no slider, or a chat widget loading before anyone has scrolled near it, are common candidates.

    For CLS

    Set an explicit width and height on every image and embed, and reserve space in the layout for anything that loads in late, ads and cookie banners included.

    See the full speed checklist, one item at a time for the complete list beyond these three, and have someone check which metric is actually failing before spending time on a fix that targets the wrong one.

    See how this is held on the retainer.

    NoDrama’s speed optimization work checks Core Web Vitals against the site on an ongoing basis, not as a one-time fix.

    See Speed Work

    Common misconceptions

    “A caching plugin fixes Core Web Vitals.”

    It improves Time to First Byte and repeat-visit LCP. It does nothing for INP, which is client-side JavaScript running after the page has already loaded, and nothing for CLS, which is a markup and layout problem.

    “The padlock and a CDN mean performance is handled.”

    A CDN helps LCP through Time to First Byte and faster asset delivery. It has no effect on the JavaScript execution behind INP or the missing dimensions behind CLS.

    “Core Web Vitals is a major ranking factor.”

    Google’s own wording, quoted above, treats it as a contributing signal that can help when content is otherwise comparably relevant, not a dominant one that overrides relevance.

    What this does not solve

    Core Web Vitals measure loading, interactivity and visual stability. They say nothing about uptime, security or content quality, and a site can pass all three metrics while having an outdated plugin or no backup in place.

    Conclusion

    Core Web Vitals are three separate metrics with three separate causes: LCP traces to hosting and image handling, INP traces to plugin JavaScript, CLS traces to unreserved layout space. Check Search Console to see which one is actually failing before changing anything, because a fix aimed at the wrong metric leaves the score exactly where it started.

  • Why Is My WordPress Site So Slow?

    Why Is My WordPress Site So Slow?

    Contents

    1. 01Work out which layer is slow. What “slow” actually means, and confirming where the time is going.
    2. 02Fix the layer that is actually slow. The three ways to fix it, from easiest to most manual.
    3. 03Confirm it is held and stop it from recurring. Verify the fix, troubleshoot the remaining edge cases, and keep it from coming back.

    What “slow” actually means for a WordPress site

    Slow is a number, not a feeling. Two numbers, in fact: time to first byte, the gap between the browser asking for the page and the server sending back the first byte of a response, and render time, how long the browser then takes to paint and settle the page a visitor actually sees.

    Google measures both through Core Web Vitals, assessed at the 75th percentile of real visits so one fast or slow load does not skew the picture. Largest Contentful Paint (LCP), the render time of the largest image or text block in the viewport, is good at 2,500 milliseconds or under. Interaction to Next Paint (INP), how quickly the page responds to a visitor’s interactions across the whole visit, is good at 200 milliseconds or under. Cumulative Layout Shift (CLS), the sum of unexpected layout shifts as the page loads, is good at 0.1 or under.

    Server response (TTFB)

    Hosting, plugins running on every request, and database queries.

    Above ~600 to 800ms flags a server-side problem

    Page weight

    Full-size images and the theme’s full CSS and JavaScript bundle.

    LCP good at 2,500ms or under

    Browser rendering

    Render-blocking scripts, stylesheets, and third-party embeds.

    INP good at 200ms or under, CLS at 0.1 or under

    All three vitals are measured at the 75th percentile of real visits. These are Google’s general Core Web Vitals thresholds, not WordPress-specific ones.

    A slow WordPress site usually comes from one of three places:

    Server-side load.

    The hosting environment, an overloaded database, or plugins that run heavier queries than they need to.

    Unoptimized front-end weight.

    Full-size images, render-blocking scripts and stylesheets, or a theme that loads its entire CSS and JS bundle regardless of what the page uses.

    No caching layer.

    Every visit reprocesses the same PHP and database work from scratch instead of serving a version already built.

    Which one applies to your site is not a guess. It is the next step.

    Confirm where the time is actually going

    Run a PageSpeed Insights check, or look at the field-data Core Web Vitals for the page, before you change anything. That gives you a TTFB number and a render-time picture to compare against once you have made a change.

    If TTFB alone is high, roughly above 600 to 800 milliseconds before any content starts, the problem is server-side: the hosting environment, the plugins running on every request, or the database being asked the same questions too many times.

    If TTFB looks fine but the page still finishes rendering slowly, the problem sits in the front end: images, render-blocking CSS or JavaScript, or third-party scripts like chat widgets, ad tags or web fonts loading synchronously.

    Verify it

    Write down the specific number, TTFB, and the Core Web Vitals reading before you touch anything. That is the only way to confirm a fix actually moved it rather than assuming it did.

    Fix it

    Option 1, easiest, recommended: page caching plus image compression

    A page cache stores the fully rendered HTML after the first PHP and database cycle runs, then serves that stored copy on repeat requests instead of running PHP and the database again. Paired with image compression, this catches the two most common causes on a typical site: repeat-visit server load and oversized static assets.

    What it misses matters as much as what it catches. A page cache does not cover logged-in visitors, cart or account pages, or any URL with a query string, all excluded from caching by design because that content is meant to be dynamic. If your slow pages are the ones a logged-in user or a shopper sees, caching alone will not touch them.

    This is also the baseline a maintenance plan should already be checking as part of ongoing upkeep, not a one-time install and forget.

    Verify it

    Re-check the TTFB and Core Web Vitals numbers from the section above, on the same page, after the cache has had time to build.

    Option 2, done for you: a CDN plus performance work as part of a managed plan

    A content delivery network (CDN) serves cacheable static assets, images, CSS, JavaScript, from an edge node physically closer to the visitor, and keeps a pre-warmed connection open to the origin server. The first request for a given asset is an origin pull, fetched from your server and cached at the edge. Every request after that is served from the edge until the cache expires.

    What a CDN cannot do is speed up PHP execution, database queries, or anything generated dynamically at the origin server on every request. If the slowness is server-side, a CDN sits on top of the problem without reaching it.

    Caching plugin CDN
    Logged-in pages Not cached Not cached
    Cart or account pages Not cached Not cached
    Static assets (images, CSS, JS) Cached at origin Cached at edge, closer to visitor
    Dynamic HTML (PHP, database output) Not touched Not touched
    Table comparing what a caching plugin and a CDN each cover, showing both miss logged-in pages and cart pages, and neither speeds up dynamic HTML.

    See how the CDN and performance work is scoped as part of a managed plan, since CDN allocation and the performance work around it are handled as ongoing configuration rather than a one-time setting.

    Verify it

    Confirm the origin pull happened (the first load of an asset after a change) and that the second load of the same asset comes from the edge, then re-check TTFB against the number you noted earlier.

    Option 3, manual: clean the database and audit plugins one at a time

    Post revisions, spam comments, expired transients, and orphaned tables accumulate in the WordPress database over time and are not purged automatically. Every uncached query against a bloated database takes measurably longer than the same query against a clean one.

    Deactivating plugins one at a time is a reasonable way to find an obvious offender, a single plugin running an expensive query on every page load. It is the longest path of the three, and it will still miss the cumulative database bloat, image weight, and theme bloat that no single plugin caused on its own.

    Verify it

    After cleaning the database or deactivating a plugin, re-run the same TTFB check and confirm the number moved before assuming the change worked.

    Verify the fix actually worked

    Re-run the same check you used to note the original number on the same page, cold. Not immediately after clearing a cache, since the first load after a cache clear rebuilds the cache and will look artificially slow. Compare the new TTFB and Core Web Vitals reading against the number you wrote down at the start. If it has not moved, the fix touched the wrong layer.

    Troubleshoot

    The site is fast on desktop but slow on mobile.

    Mobile and desktop Core Web Vitals are measured and reported separately. A fix that improves desktop LCP or INP does not automatically carry over to mobile field data. Check the mobile-specific numbers directly rather than assuming a desktop result applies.

    I installed a CDN, and nothing changed.

    This is the direct symptom of a server-side bottleneck a CDN cannot reach. A CDN only speeds up cacheable static assets served from the edge. If TTFB was already the problem, adding a CDN leaves it untouched. Re-check TTFB specifically rather than the overall load time.

    It’s fast for me but slow for everyone else.

    You are likely viewing a warmed, cached, or logged-in version of the page that a first-time or logged-out visitor does not get. Check the page from a logged-out session, ideally on a different network, before concluding the fix worked for everyone.

    Prevent it recurring

    Run the same diagnostic monthly, not just after a complaint. A monthly health report that tracks TTFB and Core Web Vitals over time catches drift before it becomes a complaint, which is what a monthly health report actually tracks as part of ongoing maintenance.

    Not sure which layer is slowing your site down?

    Send NoDrama your URL and get a free website audit, no pitch attached.

    Audit My Site

    What this does not solve

    The diagnostic above finds and addresses the common causes: server load, page weight and missing caching. It does not replace hosting that is genuinely undersized for a high-traffic site, where the fix is a hosting change, not a configuration one. It also does not audit custom code written specifically for your site, since that requires a developer familiar with the codebase, not a maintenance diagnostic.

    Google has publicly confirmed that page speed is a ranking signal. This piece does not quote a specific figure for how much it weighs, because no verifiable figure exists to quote.

    Unmaintained plugins that slow a site down are often the same plugins carrying real security exposure, so a speed audit and a security review usually turn up the same list.

    So, why is your WordPress site actually slow?

    It comes down to one of three layers: server response time, page weight, or browser rendering, and the fix depends on which one the diagnostic points to. Check TTFB first. A high number means the problem is server-side. A fine TTFB with a slow finish means the problem is in what the browser has to load and render. Fix the layer the numbers point to, not the layer that is easiest to buy a plugin for, and re-check the same numbers afterward to confirm it held.

  • How to Speed Up a WordPress Site

    How to Speed Up a WordPress Site

    The short answer

    There are seven usual suspects: slow server response, no caching, unoptimized images, a missing or misconfigured CDN, plugin or theme bloat, database bloat, and render-blocking code. None of them has a single fix that covers all seven, and treating one symptom (a slow load) as if it always has one cause is the mistake most speed advice makes.

    Server

    Slow origin response time before anything else runs.

    Caching

    No page cache, no object cache, or a cache that isn’t being hit.

    Images

    Uncompressed, oversized, or lazy-loaded above the fold.

    CDN

    Missing entirely, or configured so static files never hit the edge.

    Plugins and theme

    Queries, CSS and JavaScript added to pages that don’t use the feature.

    Database

    Revisions, expired transients and orphaned metadata piling up.

    Render-blocking code

    CSS and JavaScript that delays the first paint of the page.

    Seven possible causes of a slow WordPress site: a map of possibilities, not a priority order. The order to check them in lives in “What to do about it” below.

    The order to check them in matters more than any individual tactic. Server response and caching come first, because a slow origin server undermines everything built on top of it. Images and the CDN come next, since they’re the most visible cause on a typical page. Plugin and database cleanup come last, because they take the most care to do safely. How the speed work gets scoped breaks down what a structured pass through all seven actually looks like.

    How it actually works

    Caching, images, and the CDN

    Full-page caching serves a static, pre-built copy of a page to a visitor instead of running PHP and querying the database on every request. Object caching goes a layer deeper: it stores the results of expensive database queries so the same query doesn’t run twice. Browser caching stores static assets like CSS and images directly on the visitor’s device so a repeat visit doesn’t re-download them. Each of these solves a different part of the problem, and none of them fixes a query or a page that was slow to begin with. As Jetpack puts it, caching will hide performance issues, but it will not fix the root cause.

    Images are the biggest lever most sites have, and also where the most common piece of advice backfires. Lazy loading defers loading an image until it’s about to scroll into view, which is useful for images far down the page. Applied indiscriminately, including to the image at the top of the page, it’s measurably worse: web.dev’s own A/B test found that lazy-loading above-the-fold images made archive pages 13 to 15 percent slower on both desktop and mobile. That’s specifically because the largest above-the-fold image is usually the LCP element, the one Core Web Vitals is timing, and delaying it delays the whole measurement. WordPress core now recognizes this and doesn’t lazy-load the first featured or content image on a page for that reason.

    A CDN caches static content, images, CSS, JavaScript, at edge locations closer to the visitor, so a request travels a shorter physical distance. Cloudflare’s own illustrative figures put a request from Atlanta at roughly 1,100 milliseconds and the same request from Singapore at roughly 3,000 milliseconds without a nearby edge location, a reduction of about 63 percent with one, though that’s a directional example rather than a guarantee for any specific site. What a CDN can’t do is speed up PHP execution or a slow database query. It moves static files closer to the visitor. It doesn’t touch what happens on the origin server before those files are generated.

    Verify it

    After each change, run a Core Web Vitals check rather than trusting that the change worked. A caching or CDN change that looks right in the plugin settings can still leave LCP, INP or CLS unchanged if the actual bottleneck was somewhere else.

    Plugins and the database

    Every active plugin can add its own database queries, CSS and JavaScript to a page load, whether or not that plugin’s feature is actually being used on that page. There’s no verified number for how many plugins is too many. Any specific count offered as a safe threshold isn’t backed by a real source, so treat it as noise.

    Database bloat builds up the same way: post revisions, expired transients and orphaned metadata from removed plugins accumulate in the database and slow down the queries that run on every page load. Cleaning it up means removing rows and rebuilding indexes, and a backup before either of those steps isn’t optional. Plugin and theme updates are also a common, overlooked cause of a sudden slowdown: an update can silently change caching behavior or add a heavy new dependency, which is exactly what the update process that catches a plugin-caused slowdown is built to catch before it ships to the live site.

    Verify it

    After a database cleanup or a plugin change, re-run the Core Web Vitals check and confirm the backup taken beforehand actually restores, not just that it exists.

    Why it matters for a business site

    Google’s own documentation is more measured than most speed advice suggests. Google Search Central states plainly that Core Web Vitals are used by its ranking systems, and in the same breath that Google Search always seeks to show the most relevant content, even if the page experience is sub-par. Speed is a factor. It isn’t the only one, and a faster page that’s less relevant to the search still loses to a slower, more relevant one.

    For a small, low-traffic brochure site, a caching plugin plus a free CDN tier can genuinely be enough. The honest gap a managed service closes isn’t the initial setup, it’s what happens in the months after: a plugin update that silently disables the cache, an unoptimized image uploaded straight from a phone, or database bloat that nobody’s watching build up. None of those show up the day they happen. They show up as a slow site three months later with no obvious cause.

    What good looks like

    The benchmark is Core Web Vitals, measured at the 75th percentile and split by mobile and desktop, not a single load-time number:

    Metric Threshold for “good”
    Largest Contentful Paint (LCP) 2.5 seconds or less
    Interaction to Next Paint (INP) 200 milliseconds or less
    Cumulative Layout Shift (CLS) 0.1 or less
    Thresholds are measured at the 75th percentile, split by mobile and desktop.

    An update is one of the most common causes of a site suddenly missing one of these three, which is why testing an update before it goes live, and having a rollback if it breaks something, ties directly back to speed rather than being a separate concern. The ongoing maintenance routine that speed work depends on covers more than the update itself.

    What to do about it

    Work through these in order rather than picking the one that sounds most familiar:

    1. 01Check server response time first. If the origin server itself is slow, caching and a CDN only mask the problem for cached pages and do nothing for anything dynamic.
    2. 02Add page caching. A full-page cache serves a static copy instead of rebuilding the page on every request, which is the change most likely to matter on most sites.
    3. 03Fix above-the-fold lazy loading. Make sure the first visible image, usually the LCP element, loads eagerly rather than lazily. Reserve lazy loading for images further down the page.
    4. 04Compress and correctly size images. An oversized or uncompressed image is one of the most common reasons LCP misses the 2.5 second threshold.
    5. 05Clean up database bloat, with a backup first. Remove stale revisions, expired transients and orphaned metadata, and confirm the backup restores before making any changes.

    Every NoDrama plan includes page and browser caching, image compression and conversion, and real visitor speed data each month. Every plan gets the same global CDN. What differs is backup cadence: daily on The Standard, every 12 hours on The Higher Standard, and on every change on The Highest Standard. What’s included at each plan level has the full breakdown.

    Verify it

    After working through the list, re-run the Core Web Vitals check and compare it to the thresholds above rather than to how the site feels.

    Common misconceptions

    “Lazy-load every image.”

    Wrong for the LCP element specifically. web.dev’s own test showed lazy-loading above-the-fold images made archive pages 13 to 15 percent slower. Lazy-load what’s below the fold, not what’s above it.

    “Page speed is a major ranking factor, full stop.”

    Google’s own position is narrower than that. Core Web Vitals feed the ranking systems, but Google states directly that it still favors the more relevant page even when its page experience is worse.

    “A CDN fixes a slow site.”

    A CDN moves static content closer to the visitor. It does nothing for a slow database query or an unoptimized PHP process on the origin server, so a slow origin stays slow behind a CDN.

    What this does not solve

    None of the above fixes under-provisioned hosting. If the server itself doesn’t have the resources for the site’s traffic, caching and a CDN reduce how often that limit gets hit, but they don’t raise the limit. The same goes for a badly written theme: code that runs unnecessary queries or ships excessive CSS and JavaScript stays slow no matter how well everything around it is tuned. A full care plan covers the parts of ongoing WordPress operation that sit outside performance work specifically.

    Is my WordPress site actually slow, and what’s the fix?

    A slow WordPress site is almost always more than one problem at once: server response, caching, images, the CDN, plugins, the database and render-blocking code all contribute, and there’s no single fix that covers all seven. The honest way to check is Core Web Vitals at the 75th percentile, LCP at 2.5 seconds or under, INP at 200 milliseconds or under and CLS at 0.1 or under, worked through server response and caching first, then images and the CDN, then plugin and database cleanup, verifying with a fresh Core Web Vitals check after each step.