How to test application performance with benchmarks, Web Vitals monitoring, Lighthouse CI integration, and performance budgets that prevent regressions in bundle size and runtime metrics.
Measure function execution times to compare implementations and detect performance regressions in critical code paths using vitest bench or benchmark.js.
LCP (loading speed < 2.5s), INP (interactivity < 200ms), and CLS (visual stability < 0.1) are Google's key metrics for real-world user experience performance.
Set maximum thresholds for bundle size, request count, and timing metrics. Enforce in CI to prevent the gradual performance degradation that individual changes cause.
Automates Lighthouse audits in CI pipelines with configurable score thresholds and historical tracking to catch performance regressions before deployment.
Performance testing ensures your application meets speed and efficiency requirements and catches regressions before they reach production. Unlike functional tests that verify correctness, performance tests verify that code runs fast enough, bundles stay small enough, and user experience metrics meet thresholds.
import { bench, describe } from 'vitest';
describe('array sorting', () => {
bench('native sort', () => {
[...largeArray].sort((a, b) => a - b);
});
bench('custom quicksort', () => {
quickSort([...largeArray]);
});
});Vitest includes built-in benchmarking with vitest bench. For Jest projects, use libraries like benchmark.js or tinybench.
Load testing: Simulates concurrent users hitting your API or application to find breaking points. Tools like k6, Artillery, or autocannon stress-test server endpoints.
Bundle size testing: Monitors JavaScript bundle sizes to prevent bloat. Bundlesize, Size Limit, or bundlephobia integration catches oversized dependencies.
Lighthouse CI runs Google Lighthouse audits in your CI pipeline, scoring performance, accessibility, best practices, and SEO:
# .lighthouserc.json
{
"ci": {
"assert": {
"assertions": {
"categories:performance": ["error", { "minScore": 0.9 }],
"first-contentful-paint": ["error", { "maxNumericValue": 2000 }]
}
}
}
}Lighthouse CI can upload results to a server for historical tracking and comparison between builds.
Performance budgets are thresholds that your application must not exceed:
Enforce budgets in CI so builds fail when budgets are exceeded. This prevents the gradual performance degradation that happens when individual changes each add a small amount of weight.
size-limit: Check bundle size against a budget in CIbundlewatch: Track and compare bundle sizes across PRslighthouse-ci: Automated Lighthouse checks with configurable assertionsexperimental.outputFileTracingIncludes and bundle analyzerReact.memo and useMemo prevent unnecessary re-renderswhy-did-you-render library to detect wasteful re-renders during developmentFun Fact
Google's Core Web Vitals replaced FID (First Input Delay) with INP (Interaction to Next Paint) in March 2024 because FID only measured the delay of the first interaction, while INP measures responsiveness throughout the entire page lifecycle, giving a much more accurate picture of user experience.