By the end of the lesson, you can separate measured and perceived performance, you know the three Core Web Vitals metrics (LCP, INP, CLS) and the "good" thresholds, and from the result of a measurement you can say which intervention improves the most.
What does "fast" mean?
Imagine two web shops. The first draws a spectacular but still empty-looking interface at once: the text, the product images, and the cart button arrive only later. The second does not show every decorative element immediately, but in a moment the name and price of the product sought appear, with a working "Add to cart" button. It is possible that by a technical measure the first page "finishes" loading in a shorter time, yet the second seems faster. The user does not live through a network log, but the completion of a task.
That is why we separate measured performance (durations, sizes, processor use, browser events) from perceived performance (when the visitor feels that the page is usable, has responded to their click, and the content does not jump from under them). The two are related, but not identical. According to lesson 3.3 the "loaded" state is not a single moment; here we examine how well which metrics approximate the user experience.
The speed of a page is shaped by several phases: name resolution, connection, fetching the document (chapter 4), downloading further resources, then processing on the device: DOM, layout, painting, and running JavaScript (3.3). On a weak phone the same JavaScript can take much longer than on a developer's laptop.
flowchart LR
N[Network and server] --> L[LCP: appearance of the main content]
J[JavaScript load] --> I[INP: reaction to the action]
M[Unsized media] --> C[CLS: jumping of the layout]
L --> E[User experience]
I --> E
C --> E
Core Web Vitals: three viewpoints
The Core Web Vitals are a set of widely used metrics that approximate the user experience from the side of loading, interaction, and visual stability. The "good" thresholds according to web.dev:
Metric
What does it measure?
"Good" value
LCP (Largest Contentful Paint)
When does the largest visible content element appear (main heading, hero image, large text block)?
at most 2.5 seconds
INP (Interaction to Next Paint)
After a user action (click, tap, key press), how much time passes until the next visible feedback?
at most 200 milliseconds
CLS (Cumulative Layout Shift)
How much does the layout jump unexpectedly?
at most 0.1
Web.dev recommends doing the evaluation at the 75th percentile of page loads, separately for mobile and desktop: the page passes if all three metrics reach the target at this percentile. (The percentile is the value below which 75 percent of the measurements lie, that is, we do not treat the slower quarter as an exception.) INP became a stable Core Web Vital in 2024, and replaced the earlier FID (First Input Delay) metric.
The metrics are not complete ratings: they do not say whether the page is accessible, understandable, or handles data lawfully. They do, however, help notice some very common, annoying problems.
LCP: arrival of the main content
For the visitor, LCP is the moment when the main message of the page arrives. If the opening image is too large, in a bad format, starts downloading late, or the server sends the HTML slowly, the LCP gets worse. The conclusion is not that "every image must be dropped", but that the image must be delivered in the right size, format, and priority (3.4, 9.3). Optimizing a tiny icon helps little if the main product image is 8 megabytes.
INP: feedback after the action
If, after clicking the "Pay" button, nothing happens for a long time, the user may press it again, think they made a mistake, or leave the page. INP is not exclusively a network response time: in many cases it is bad because the browser is just processing a large amount of JavaScript, and a long task occupies the main thread, so the processing of the click waits. A good principle: the interface should give clear, immediate feedback (a loading state, a disabled button), and we should split costly work into smaller parts.
CLS: the unexpected jump
Everyone has experienced that just as they touch a link, a late-loading image pushes the content down, and the click lands on another element. A typical cause is that the image or embedded content has no space reserved in advance. The solution is to give the size (width and height, 3.3) and to keep space for dynamic elements. Content that appears intentionally in response to the user's action (for example an expanded menu) can of course change the layout; the problem is the unexpected change.
Tried in the lab: the same page bad and good
The two pages already used in lesson 9.2 (a deliberately faulty and a fixed course page) were measured with version 13.5.0 of Lighthouse, in a Chrome 154 browser, in a simulated mobile environment (Lighthouse's default throttled network and processor). The server artificially delayed the style sheet (0.9 s), the JavaScript (0.6 s), and the large image (0.4 s). The faulty page loaded a 1.35-megabyte image without a size, the JavaScript blocked the thread for 0.4 s, and a banner was inserted at the top of the page after 1.5 s. The fixed page used a 150-kilobyte, sized image, received the styles inline, and its JavaScript was deferred and short.
Metric
Faulty page
Fixed page
Good threshold
Performance score (0–100)
68
100
–
First Contentful Paint (FCP, the first content)
3.3 s
0.8 s
–
LCP
8.5 s
1.8 s
≤ 2.5 s
Total Blocking Time (TBT)
0 ms
0 ms
–
CLS
0.019
0
≤ 0.1
Speed Index
3.9 s
0.8 s
–
(Lighthouse is a lab measurement: a single load, a simulated environment. It does not measure INP, because that needs an actual user action; in the lab TBT, the main-thread blocking during loading, approximates INP, according to web.dev.)
What can we read from this?
LCP is the main problem: 8.5 s, more than three times the threshold. Lighthouse reported two main causes: render-blocking requests (the delayed style sheet and the script; estimated saving 2,260 ms) and image delivery (estimated saving 1,246 KiB, that is, the image being too large).
CLS is small here (0.019), within the "good" threshold. The inserted banner was visible, but the measured shift stayed small; CLS therefore should not be judged "by feel" but measured. Lighthouse, however, reported the unsized image (unsized-images) as a separate error, because this is a risk of later shifting.
TBT is 0 ms on both pages, even though the JavaScript of the faulty page occupied the thread for 0.4 s. The blocking happened before the first content (because of the parser-blocking script), whereas TBT counts the blocking after the first content. This is a good example of how a single metric does not show everything: the blocking script is visible in FCP and LCP.
The fix is not cosmetics for the metrics: the smaller image, the inline style, and defer are exactly the steps that give the user a faster, more stable experience too (3.4).
Lighthouse also reported a console error on the fixed page: the browser requested favicon.ico and got a 404. This does not affect performance, but it lowered the "best practices" score to 92. Every detail of the measurement depends on the environment, so the results should be regarded as for comparison, not absolute truth.
Latency: file size is not all that counts
Latency (4.6) is the time that passes between starting a request and the arrival of the response. A small response can be slow if the server starts answering only after a long time; a larger image can arrive acceptably if it is served from nearby, over a fast network, and with a well-organized download. It is useful to think separately about the first byte of the response (4.2: TTFB) and the whole response: if the server waits for the database, the browser gets nothing for a long time, and the visitor sees an empty screen. Besides the network, many large or badly scheduled scripts on the page can also occupy the browser's main thread; then the files may even have downloaded, but the interface does not respond. The "number of megabytes" is therefore not enough.
Images, JavaScript, and cache
Images: they often make up most of the downloaded data. Needlessly high resolution, weak compression, or a phone receiving a giant image meant for a desktop all worsen LCP. Several versions can be offered to the browser (9.3). The main image must not be delayed, but a gallery at the bottom of the page may be (3.4).
JavaScript: it provides rich interaction, but its download, processing, and running are a load. An external measuring script, a chat window, an advertising system can all increase the cost. The question is not whether JavaScript may be used, but whether all code serves a real user purpose, and when it should be loaded.
Cache: reusing previously downloaded, still valid resources reduces waiting. Chapter 10 discusses the details (HTTP cache, CDN).
What and how do we measure?
The network view of the browser's developer tools shows which request took how long, how large the response was, and whether it came from the cache. The performance profile shows if a long JavaScript task blocks the interface. We cannot interpret these in isolation: always ask which user task suffers, and which change would improve it the most.
Worked example: the enrolment page of Kurzuspont
On the enrolment page of Kurzuspont, students complain that it is "slow" on opening. The team works in the following order: (1) it measures LCP, TBT, and CLS in the lab, and INP as well in the real data; (2) it looks at what the LCP element is (the photo of the course); (3) it serves the image in the right size, narrows the style to the critical part, and loads the script with defer; (4) it gives instant feedback on the "Enrol" button (a disabled state, "Sending..."); (5) it checks the real data at the 75th percentile. The measure of success is not the score, but that the student quickly finds and safely uses the enrolment.
Common misconceptions
Statement
Clarification
"Performance is only the server's business."
Images, browser-side code, fonts, and third-party elements are decisive too.
"On a fast internet every page is fast."
Connection speed does not solve a slow server response, too many requests, or blocking JavaScript.
"Good Core Web Vitals = a good website."
They give a signal about only a few dimensions; they do not examine usability and accessibility.
"A 100-point Lighthouse result is 100 for real users too."
It is a lab measurement: real devices and networks differ.
"Everything must be cached."
A faulty rule can serve old content or content meant for another user (chapter 10).
In brief
Performance is the user's experience (perceived), not only durations (measured).
Core Web Vitals: LCP (≤ 2.5 s), INP (≤ 200 ms), CLS (≤ 0.1), evaluated at the 75th percentile.
A lab measurement is good for comparison, real field data shows the actual impact.
On the tried faulty page the large image and the render-blocking requests caused the 8.5 s LCP; the fix reduced it to 1.8 s.
No single metric shows everything (TBT was 0 here despite the blocking script).
Review questions
What is the difference between measured and perceived performance?
What do LCP, INP, and CLS measure, and what is their "good" threshold?
Why was TBT 0 on the faulty page while the script blocked the thread?
Why is it not enough to evaluate a page with a single lab measurement?
User-perceived performance
Objectives
By the end of the lesson, you can separate measured and perceived performance, you know the three Core Web Vitals metrics (LCP, INP, CLS) and the "good" thresholds, and from the result of a measurement you can say which intervention improves the most.
What does "fast" mean?
Imagine two web shops. The first draws a spectacular but still empty-looking interface at once: the text, the product images, and the cart button arrive only later. The second does not show every decorative element immediately, but in a moment the name and price of the product sought appear, with a working "Add to cart" button. It is possible that by a technical measure the first page "finishes" loading in a shorter time, yet the second seems faster. The user does not live through a network log, but the completion of a task.
That is why we separate measured performance (durations, sizes, processor use, browser events) from perceived performance (when the visitor feels that the page is usable, has responded to their click, and the content does not jump from under them). The two are related, but not identical. According to lesson 3.3 the "loaded" state is not a single moment; here we examine how well which metrics approximate the user experience.
The speed of a page is shaped by several phases: name resolution, connection, fetching the document (chapter 4), downloading further resources, then processing on the device: DOM, layout, painting, and running JavaScript (3.3). On a weak phone the same JavaScript can take much longer than on a developer's laptop.
flowchart LR N[Network and server] --> L[LCP: appearance of the main content] J[JavaScript load] --> I[INP: reaction to the action] M[Unsized media] --> C[CLS: jumping of the layout] L --> E[User experience] I --> E C --> ECore Web Vitals: three viewpoints
The Core Web Vitals are a set of widely used metrics that approximate the user experience from the side of loading, interaction, and visual stability. The "good" thresholds according to web.dev:
Web.dev recommends doing the evaluation at the 75th percentile of page loads, separately for mobile and desktop: the page passes if all three metrics reach the target at this percentile. (The percentile is the value below which 75 percent of the measurements lie, that is, we do not treat the slower quarter as an exception.) INP became a stable Core Web Vital in 2024, and replaced the earlier FID (First Input Delay) metric.
The metrics are not complete ratings: they do not say whether the page is accessible, understandable, or handles data lawfully. They do, however, help notice some very common, annoying problems.
LCP: arrival of the main content
For the visitor, LCP is the moment when the main message of the page arrives. If the opening image is too large, in a bad format, starts downloading late, or the server sends the HTML slowly, the LCP gets worse. The conclusion is not that "every image must be dropped", but that the image must be delivered in the right size, format, and priority (3.4, 9.3). Optimizing a tiny icon helps little if the main product image is 8 megabytes.
INP: feedback after the action
If, after clicking the "Pay" button, nothing happens for a long time, the user may press it again, think they made a mistake, or leave the page. INP is not exclusively a network response time: in many cases it is bad because the browser is just processing a large amount of JavaScript, and a long task occupies the main thread, so the processing of the click waits. A good principle: the interface should give clear, immediate feedback (a loading state, a disabled button), and we should split costly work into smaller parts.
CLS: the unexpected jump
Everyone has experienced that just as they touch a link, a late-loading image pushes the content down, and the click lands on another element. A typical cause is that the image or embedded content has no space reserved in advance. The solution is to give the size (
widthandheight, 3.3) and to keep space for dynamic elements. Content that appears intentionally in response to the user's action (for example an expanded menu) can of course change the layout; the problem is the unexpected change.Tried in the lab: the same page bad and good
The two pages already used in lesson 9.2 (a deliberately faulty and a fixed course page) were measured with version 13.5.0 of Lighthouse, in a Chrome 154 browser, in a simulated mobile environment (Lighthouse's default throttled network and processor). The server artificially delayed the style sheet (0.9 s), the JavaScript (0.6 s), and the large image (0.4 s). The faulty page loaded a 1.35-megabyte image without a size, the JavaScript blocked the thread for 0.4 s, and a banner was inserted at the top of the page after 1.5 s. The fixed page used a 150-kilobyte, sized image, received the styles inline, and its JavaScript was
deferred and short.(Lighthouse is a lab measurement: a single load, a simulated environment. It does not measure INP, because that needs an actual user action; in the lab TBT, the main-thread blocking during loading, approximates INP, according to web.dev.)
What can we read from this?
unsized-images) as a separate error, because this is a risk of later shifting.deferare exactly the steps that give the user a faster, more stable experience too (3.4).Lighthouse also reported a console error on the fixed page: the browser requested
favicon.icoand got a404. This does not affect performance, but it lowered the "best practices" score to 92. Every detail of the measurement depends on the environment, so the results should be regarded as for comparison, not absolute truth.Latency: file size is not all that counts
Latency (4.6) is the time that passes between starting a request and the arrival of the response. A small response can be slow if the server starts answering only after a long time; a larger image can arrive acceptably if it is served from nearby, over a fast network, and with a well-organized download. It is useful to think separately about the first byte of the response (4.2: TTFB) and the whole response: if the server waits for the database, the browser gets nothing for a long time, and the visitor sees an empty screen. Besides the network, many large or badly scheduled scripts on the page can also occupy the browser's main thread; then the files may even have downloaded, but the interface does not respond. The "number of megabytes" is therefore not enough.
Images, JavaScript, and cache
What and how do we measure?
The network view of the browser's developer tools shows which request took how long, how large the response was, and whether it came from the cache. The performance profile shows if a long JavaScript task blocks the interface. We cannot interpret these in isolation: always ask which user task suffers, and which change would improve it the most.
Worked example: the enrolment page of Kurzuspont
On the enrolment page of Kurzuspont, students complain that it is "slow" on opening. The team works in the following order: (1) it measures LCP, TBT, and CLS in the lab, and INP as well in the real data; (2) it looks at what the LCP element is (the photo of the course); (3) it serves the image in the right size, narrows the style to the critical part, and loads the script with
defer; (4) it gives instant feedback on the "Enrol" button (a disabled state, "Sending..."); (5) it checks the real data at the 75th percentile. The measure of success is not the score, but that the student quickly finds and safely uses the enrolment.Common misconceptions
In brief
Review questions
Learning resources