Performance evaluation metrics
Performance is judged not by a single number but by a set of metrics covering four levels: page loading in the browser, JavaScript execution, server behaviour and the subjective feeling of speed. In an interview you are expected to name the Core Web Vitals and explain what measures each level.
Theory
TL;DR
- Browser: FCP, LCP, INP, CLS, TTFB, TBT. Three of them, LCP, INP and CLS, form the Core Web Vitals.
- JavaScript: execution time, memory usage, garbage collector pauses, event loop lag, FPS, style, layout and paint time.
- Backend: latency, throughput (RPS), error rate, CPU, memory, event loop delay, database query time, cache hit ratio.
- UX: TTI, user timing marks, perceived performance.
- Composite indexes: Speed Index, Lighthouse Performance Score, Core Web Vitals Score.
- All of it is collected through Lighthouse, PageSpeed Insights, the Performance API, the web-vitals SDK, Chrome DevTools, Prometheus and Grafana.
Quick example
// Custom time marks through the User Timing API
performance.mark('render-start');
renderList(items);
performance.mark('render-end');
performance.measure('render', 'render-start', 'render-end');
const [entry] = performance.getEntriesByName('render');
console.log(`render: ${entry.duration.toFixed(1)} ms`);
// Page navigation metrics, TTFB among them
const [nav] = performance.getEntriesByType('navigation');
console.log('TTFB:', nav.responseStart - nav.requestStart, 'ms');Frontend performance metrics
These metrics evaluate how fast and how smoothly the page loads and responds:
| Metric | What it measures | Good value |
|---|---|---|
| FCP (First Contentful Paint) | Time to the first painted content (text, image) | < 1.8 s |
| LCP (Largest Contentful Paint) | Time to display the largest content element (a banner or image, for example) | < 2.5 s |
| FID (First Input Delay) | Delay between the user's first action (click, scroll) and the page reacting | < 100 ms |
| INP (Interaction to Next Paint) | How fast the interface responds to user actions (the newer metric, replaces FID) | < 200 ms |
| CLS (Cumulative Layout Shift) | How much content shifts around during loading | < 0.1 |
| TTFB (Time To First Byte) | Time until the first byte of the server response arrives | < 0.6 s |
| TBT (Total Blocking Time) | Total time the main thread is blocked and unable to respond | < 200 ms |
These metrics are collected through:
- Lighthouse, PageSpeed Insights;
- the Performance API (
performance.getEntriesByType('navigation')); - the Web Vitals SDK.
JavaScript performance metrics
For judging how fast and how efficient the JS code itself is:
| Metric | What it evaluates |
|---|---|
| Execution time | Runtime of a chunk of code (for example with console.time() or performance.now()) |
| Memory usage | Memory consumption (performance.memory.usedJSHeapSize) |
| Garbage collection time | Frequency and length of GC pauses |
| Event loop lag / latency | How badly the main thread is blocked |
| FPS (Frames per second) | Interface refresh rate (should be 60 FPS) |
| Recalculate Style / Layout / Paint time | Time spent on painting and rebuilding the DOM |
| Script parse/compile time | Time spent parsing and compiling JS files |
The tools used are:
- Chrome DevTools, the Performance tab;
- React Profiler, Vue DevTools;
- Lighthouse, the «Diagnostics» section.
Backend performance metrics
When the subject is Node.js, NestJS, Express or any API service:
| Metric | What it shows |
|---|---|
| Response Time / Latency | Average server response time |
| Throughput (RPS) | Number of requests per second |
| Error rate | Share of failed requests (4xx/5xx) |
| CPU usage | Processor load |
| Memory usage (RSS, heap) | Memory consumption |
| Event loop delay | How badly the event loop is blocked |
| DB query time | Average SQL query duration |
| Cache hit ratio | Caching effectiveness |
For measurement people use:
- Prometheus and Grafana;
- New Relic, Datadog, Sentry Performance;
- the
performanceAPI built into Node.js (perf_hooks).
User experience metrics and composite indexes
UX metrics describe not isolated milliseconds but how comfortable the page feels:
| Metric | What it reflects |
|---|---|
| TTI (Time To Interactive) | When the page becomes fully interactive |
| TBT + INP | How comfortable interaction is |
| User timing marks | Your own points via performance.mark() and performance.measure() |
| Perceived performance | The subjective sense of speed created by skeletons, lazy loading and prefetch |
Above all of these sit the composite indexes:
| Metric | Composite characteristic |
|---|---|
| Speed Index | How quickly all content becomes visually complete |
| Performance Score (Lighthouse) | An aggregate score from 0 to 100 |
| Core Web Vitals Score | Google's metric for SEO and UX |
A short summary:
For the browser: FCP, LCP, INP, CLS, TBT. For JS code: execution time, memory, FPS, GC. For the server: latency, RPS, CPU, DB time. For UX: TTI, Speed Index, user timings.
Common mistakes
- Quoting only the Lighthouse Score. It is a derived number; the interviewer wants the concrete metrics it is built from.
- Presenting FID as the current metric. Since 2024 INP has replaced FID in the Core Web Vitals, FID is now historical.
- Relying on lab data alone. Lighthouse on a powerful laptop says one thing, real users (RUM, field data) another; you need both sources.
- Measuring averages instead of percentiles. Latency and INP are judged at p75 or p95, because an average hides the tail of slow sessions.
- Confusing TTFB with load time. TTFB is only the first byte of the response; the page can stay blank for seconds after it.
- Trusting
performance.memory. It is a non-standard property, available mostly in Chromium and with deliberately coarsened values. - Optimising without measuring. Profile in DevTools first, change code second, otherwise effort goes into parts that decide nothing.
Short Answer
Interview readyA concise answer to help you respond confidently on this topic during an interview.