Performance Testing
Core Web Vitals and Performance Testing: Beyond the Load Test
Load testing answers "does the backend survive traffic." It says nothing about whether a single real user, on a real device, on a real network, experiences the page as fast.
Those are different questions with different failure modes. A team that only measures one of them is flying blind on the other.
What each Core Web Vital actually measures, and the thresholds that count
- Largest Contentful Paint (LCP). How long until the biggest visible element renders. Google's published thresholds: under 2.5 seconds is good, 2.5 to 4 seconds needs improvement, over 4 seconds is poor. This is dominated by render-blocking resources and unoptimized images, not backend response time alone.
- Interaction to Next Paint (INP). How long the page takes to respond after a click or keypress. Under 200ms is good, over 500ms is poor. A page that loaded fast but freezes for 300ms on every click sits in the "needs improvement" band even with a perfect LCP score.
- Cumulative Layout Shift (CLS). How much visible content shifts unexpectedly after load, scored on a unitless scale where under 0.1 is good and over 0.25 is poor. Images without reserved dimensions and late-injected banners are the usual cause.
A page can be technically fast and still fail all three if it loads quickly, freezes on the first click, and then jumps half a screen once an ad slot resolves.
Synthetic vs. real-user measurement
Synthetic testing (Lighthouse, WebPageTest) runs a fixed script against a controlled environment: consistent, repeatable, and good for catching regressions in CI before they ship. Real-user monitoring (RUM) captures actual Core Web Vitals from real visitors, across their actual devices and network conditions, which vary far more than any synthetic run does.
The two disagree more often than teams expect. A page can score well synthetically, from a fast CI runner on a fast connection, while real users on mid-range phones and spotty networks experience it as genuinely slow. Treat synthetic scores as a pre-ship gate and RUM as the actual source of truth for what's happening in production.
How this connects to load testing
Load testing and Core Web Vitals testing catch different failures at different layers, and neither substitutes for the other. A backend that handles thousands of concurrent users without an error, as covered in what load testing numbers actually tell you, can still ship a frontend that blocks rendering on an unoptimized bundle for every single one of those users.
Run both: load tests to confirm the backend survives real traffic, and Core Web Vitals tracking to confirm what "survives" actually feels like on the other end of the connection.
We tie performance testing engagements to both layers, because a passing load test and a fast-feeling product are related but genuinely separate outcomes.