Same thresholds, different sites
Google measures LCP, INP and CLS the same way whatever built the page. A WordPress site and a Next.js site are graded on the same numbers. But the two stacks fail in characteristically different ways, and a fix that is a plugin toggle on one is an architectural change on the other. Knowing the pattern shortens the diagnosis.
Across the sites we have audited, here is where each stack tends to break, and why.
LCP
WordPress fails LCP on the server and on images. Time to first byte is the first problem: PHP generating the page on every request when the cache is not hitting, on shared hosting, with twenty plugins. Then the LCP image: a theme rendering the hero as a CSS background with no srcset, loading="lazy" applied by default to template images, uploads served at original size. The fix is caching (full-page at the edge, object cache behind it), then image handling (a real <img>, fetchpriority="high", sized variants), then trimming the plugins that load assets everywhere.
Next.js fails LCP on discovery and on dynamic rendering. TTFB is usually good, because pages are static or cached at the edge, unless a route is accidentally dynamic (reads cookies, uses Date.now(), missing use cache) and renders per request through a cold function. The LCP image problem is different in shape: next/image without priority lazy-loads the hero; without honest sizes it serves the desktop image to phones; a client-rendered hero component delays discovery until hydration. The fixes are a priority prop, a sizes attribute, and making sure the hero is a server component in the initial HTML.
What the platform decides: Next.js makes fast TTFB the default and slow TTFB a mistake; WordPress makes it a hosting and caching decision you have to make well. Image handling is solvable on both, and both get it wrong out of the box in different ways.
INP
WordPress fails INP on plugins and page builders. Every plugin that enqueues a script on every page adds to main-thread time; a builder's runtime initialising every widget adds more; jQuery plugins for sliders, animations and menus attach handlers to everything. The tag manager and chat widget sit on top. Interactions are slow because the thread is busy with things unrelated to the interaction. The fix is subtraction: dequeue scripts per page, remove unused plugins, tune or leave the builder, defer third parties.
Next.js fails INP on hydration and client trees. The characteristic failure is a tap during hydration, where the framework is attaching handlers to a large client tree and the tap waits. Then wide re-renders: state high in the tree, a keystroke re-rendering a hundred components. The fix is structural: server components by default, 'use client' at the leaves, state moved down, Suspense boundaries so the tapped island hydrates first, the React Compiler for memoisation. Third parties are the same problem on both stacks.
What the platform decides: WordPress INP is mostly about what was installed; Next.js INP is mostly about how the tree was structured. The WordPress fix is often faster (uninstall things); the Next.js fix is often more durable (the architecture stays right).
CLS
WordPress fails CLS on injected content. Images inserted by editors without dimensions in the content; widgets (reviews, maps, social feeds) injected by shortcode with no reserved space; a cookie banner plugin pushing the page down; a font swap from a theme loading Google Fonts late; a builder animating elements into position. The fix is dimensions on content images (the platform mostly does this now), reserved boxes around every embed, an overlay banner, self-hosted fonts with metric overrides.
Next.js fails CLS on client-only rendering and fonts. A component that renders null on the server and content on the client (a theme toggle, a client-side date, a useEffect-gated section) shifts when it appears. next/image prevents image shifts if used; a raw <img> from MDX does not. next/font prevents font shifts if used; a stylesheet @import of a web font does not. The fix is rendering the same thing on server and client, using the framework's image and font components, and Suspense fallbacks sized like their content.
What the platform decides: Next.js's Image and font components make the two biggest CLS sources solved-by-default when used. WordPress has caught up on images and still leaves fonts and embeds to the theme.
What each stack makes easy
WordPress: adding capability without a developer, which is also how it gets slow. Fixing performance often means removing things, which is quick. Caching plugins and managed hosts do a great deal automatically. The ceiling is lower: a tuned WordPress site with a good theme lands in Good; a tuned page-builder site often does not.
Next.js: performance-correct defaults for the things the framework controls (routing, images, fonts, code splitting, edge caching), and a high ceiling. Getting it wrong requires either fighting the framework (client components everywhere) or third parties, and fixing it requires a developer. There is no plugin toggle.
What the platform does not decide
- Third-party scripts. The tag manager, chat widget, replay SDK and consent banner are identical costs on both stacks and are the top INP cause on well-built sites of either kind.
- Content discipline. A 4 MB hero uploaded by a marketer is 4 MB on either platform unless the pipeline caps it.
- Hosting quality, for WordPress especially, and function configuration for Next.js.
- Whether anyone is monitoring. Both drift. Both need field data watched.
Choosing on performance grounds
If performance is the deciding factor and the site will have a developer, Next.js has the higher ceiling and the better defaults. If the site will be maintained by non-developers and performance needs to be "good enough" rather than best, a WordPress block theme on managed hosting with a care plan gets there and stays there with less specialist input. A page-builder WordPress site, tuned, usually lands at Needs improvement, and that is a known ceiling worth stating before the site is built.
Where this sits
We audit and fix both, which is why the pattern above is written from evidence rather than preference. The Core Web Vitals audit starts the same way on either stack (field data, then traces), and the fix list looks different in exactly the ways described, which is useful to know before deciding what to build.