Web QoE Scoring Model¶
Note
This model is currently in beta. We welcome feedback on the scoring methodology and curve parameters, and we are currently evaluating it in practical situations.
The Web QoE Score is an overall Quality of Experience score for web page loads, expressed on a 0–100 scale. It combines multiple web performance metrics into a single value that answers a simple question: "How good was this page load for the user?" The score is provided as the statistic value web_qoe_score.
By default, the score is calculated from three metrics: First Contentful Paint (FCP), Largest Contentful Paint (LCP), and Time to First Byte (TTFB). These are the metrics that can be reliably measured in automated tests, which is how Surfmeter collects web performance data. Other metric combinations are supported as well, and are described under alternative metric sets below.
How it works¶
Each web performance metric is scored individually on a 0–100 scale using a log-normal scoring curve. The individual scores are then combined into a single weighted average — the Web QoE Score.
The scoring curve is an S-shaped function that maps raw metric values (like "1.2 seconds for first paint") to a quality score. Fast values score close to 100, slow values score close to 0, and the transition between good and bad is smooth rather than abrupt. Two parameters define each curve:
- p10 — the metric value at which the score reaches approximately 90 (the "good" threshold). Values better than this produce diminishing returns in the score.
- median — the metric value at which the score is approximately 50. This represents the boundary between acceptable and poor performance.
This approach is based on Google's Lighthouse performance scoring methodology, which describes the process as follows:
The Lighthouse scoring curve model uses HTTPArchive data to determine two control points that then set the shape of a log-normal curve. The 25th percentile of HTTPArchive data becomes a score of 50 (the median control point), and the 8th percentile becomes a score of 90 (the good/green control point). Between 0.50 and 0.92, there's a near-linear relationship between metric value and score. Around a score of 0.96 is the "point of diminishing returns" as higher, the curve pulls away, requiring increasingly more metric improvement to improve an already high score.
— Lighthouse Performance Scoring, Google Chrome Developers
Google also provides a Lighthouse scoring calculator and a graphing function for exploring the log-normal curve behavior.
Score interpretation¶
The Web QoE Score can be interpreted using a simple traffic-light scheme:
| Score range | Rating | Meaning |
|---|---|---|
| 90–100 | 🟢 Good | The page loaded quickly. Users are unlikely to notice any performance issues. |
| 50–89 | 🟡 Needs improvement | The page load was noticeably slow. Users may be mildly frustrated. |
| 0–49 | 🔴 Poor | The page load was significantly below expectations. Users are likely to abandon the page or have a bad experience. |
These thresholds follow the same 90/50 boundaries used by Lighthouse for its performance score.
Input metrics¶
The default metric set uses the following three metrics:
- FCP – First Contentful Paint: when the first content appears on screen.
- LCP – Largest Contentful Paint: when the page's main content has likely loaded.
- TTFB – Time to First Byte: server response time (also called Server Response Time).
TTFB is partly contained in the other two metrics — a slow server delays both the first and the largest paint. It is still scored separately, because it isolates the network and server part of the page load from the rendering part. A page that renders slowly because of heavy JavaScript and a page that renders slowly because the connection is bad both show poor FCP and LCP values, but only the second one shows a poor TTFB. In this sense, TTFB acts as a proxy for network conditions, which makes it valuable for network-focused monitoring.
Two further Web Vitals metrics are deliberately not part of the default set:
- INP – Interaction to Next Paint: measures responsiveness to user interactions. It requires a real user clicking, tapping, or typing, so it cannot be measured in automated tests at all. Measuring it requires Real User Monitoring (RUM).
- CLS – Cumulative Layout Shift: measures visual stability during loading. Many measurement environments do not report it, and when they do, it is frequently zero, which contributes little information to the score.
Where these two metrics can be measured, they are still recorded and reported as statistic values of their own — they are simply not part of the score. Keeping them out of it also keeps scores comparable: because a CLS of 0 is a valid measurement rather than a missing one, letting CLS into the calculation would mean that the same page scores differently depending on whether the browser happened to report a layout shift at all.
Total Blocking Time (TBT) is not used either, as it is not directly measurable in all environments. Similarly, the Speed Index (SI) is not used, as it is difficult to measure.
Note
The default score reflects loading performance only. It cannot capture interactivity or visual stability problems: a page with fast paint times but sluggish responsiveness or jumping content will still score well.
Scoring curves¶
The curves for the default metric set are aligned to the Web Vitals thresholds: the p10 value of each curve is the Web Vitals "good" threshold, and the median is the "poor" threshold.
| Metric | median (= "poor" threshold) | p10 (= "good" threshold) | Weight |
|---|---|---|---|
| FCP | 3000 ms | 1800 ms | 0.20 |
| LCP | 4000 ms | 2500 ms | 0.50 |
| TTFB | 1800 ms | 800 ms | 0.30 |
The weights are the relative Lighthouse weights of these three metrics (0.10, 0.25, and 0.15), renormalized to sum to 1. LCP carries the most weight, as it is the metric that best represents when the page becomes useful to the user.
These curves are identical for PC and mobile device types, since the Web Vitals thresholds do not distinguish between the two.
Aligning the curves to the Web Vitals thresholds means that a page which just meets all "good" thresholds scores 90, and a page at the "poor" thresholds scores 50 — matching the score interpretation above. The Lighthouse curves are not used here, because they are calibrated for a set in which CLS and INP — which tend to score high — compensate for the much stricter paint-time curves. Applying the Lighthouse PC curves to FCP, LCP, and TTFB alone would give a page that meets every Web Vitals "good" threshold a score of only 58, which is not a useful result.
Effect of TTFB on the score¶
The following table illustrates how much the server response time moves the overall score. FCP and LCP are held at their "good" thresholds (1.8 s and 2.5 s), and only TTFB varies:
| TTFB | TTFB metric score | Web QoE Score |
|---|---|---|
| 0.2 s | 100 | 93 |
| 0.8 s | 90 | 90 |
| 1.2 s | 74 | 85 |
| 1.8 s | 50 | 78 |
| 2.5 s | 30 | 72 |
| 4.0 s | 10 | 66 |
Example scores¶
The following table shows scores for the PC device type at the Web Vitals tier boundaries:
| Scenario | FCP | LCP | TTFB | Web QoE Score | Rating |
|---|---|---|---|---|---|
| Excellent | 0.5 s | 1.0 s | 0.2 s | 100 | Good |
| Good (Web Vitals "good" thresholds) | 1.8 s | 2.5 s | 0.8 s | 90 | Good |
| Needs improvement (Web Vitals "poor" thresholds) | 3.0 s | 4.0 s | 1.8 s | 50 | Needs improvement |
| Poor | 5.0 s | 6.0 s | 3.0 s | 15 | Poor |
And here are scores for a set of typical websites:
| Scenario | FCP | LCP | TTFB | Web QoE Score | Rating |
|---|---|---|---|---|---|
| Fast CDN-served landing page | 0.6 s | 0.9 s | 0.15 s | 100 | Good |
| Well-optimized news site | 1.2 s | 2.0 s | 0.4 s | 98 | Good |
| Typical corporate website | 2.0 s | 3.0 s | 0.9 s | 82 | Needs improvement |
| Heavy SPA (React/Angular) | 2.8 s | 3.5 s | 0.6 s | 72 | Needs improvement |
| Ad-heavy media site | 3.5 s | 5.0 s | 1.2 s | 43 | Poor |
| Slow shared hosting blog | 4.5 s | 7.0 s | 2.5 s | 15 | Poor |
| Overloaded e-commerce site | 5.5 s | 8.0 s | 3.5 s | 7 | Poor |
| Broken/failing site | 12 s | 18 s | 6.0 s | 1 | Poor |
The heavy SPA is a good illustration of what the score expresses: its server responds quickly (TTFB 0.6 s, scoring 96 on its own), but the page takes a long time to render, so the overall score still lands in the middle of the "needs improvement" range.
Alternative metric sets¶
Besides the default set, the scoring model supports a few other metric combinations, for platforms that provide different data. Surfmeter measurements do not use them: their score is always calculated from FCP, LCP, and TTFB, even when CLS was measured. The sets below therefore only come into play when the scoring function is called directly with other metrics, and any combination not listed here produces no score at all.
FCP and LCP only¶
When TTFB is not available, the score is calculated from FCP and LCP alone, using the same Web Vitals threshold-aligned curves with equal weights of 0.5 each. At the tier boundaries this produces the same scores as the default set (90 at "good", 50 at "poor"), so the two remain broadly comparable. Away from the boundaries, results differ where server response time and rendering time diverge — the heavy SPA above scores 72 with TTFB included and 61 without it.
Sets including CLS and INP¶
Three further sets exist for platforms that report CLS, and optionally INP. These use the original Lighthouse v10 curves and weights:
| Metric | PC median | PC p10 | Mobile median | Mobile p10 | Weight |
|---|---|---|---|---|---|
| FCP | 1600 ms | 934 ms | 3000 ms | 1800 ms | 0.10 |
| LCP | 2400 ms | 1200 ms | 4000 ms | 2500 ms | 0.25 |
| CLS | 0.25 | 0.1 | 0.25 | 0.1 | 0.25 |
| INP | 500 ms | 200 ms | 500 ms | 200 ms | 0.25 |
| TTFB | 1800 ms | 800 ms | 1800 ms | 800 ms | 0.15 |
The three combinations are:
- Full (5 metrics): FCP, LCP, CLS, INP, and TTFB. Requires Real User Monitoring data for INP.
- 4 metrics without INP: FCP, LCP, CLS, and TTFB, as produced by Lighthouse in lab mode. INP's weight of 0.25 is redistributed proportionally among the remaining four, giving effective weights of approximately FCP 0.13, LCP 0.33, CLS 0.33, TTFB 0.20.
- 4 metrics without TTFB: FCP, LCP, CLS, and INP. TTFB's weight of 0.15 is redistributed the same way, giving approximately FCP 0.12, LCP 0.29, CLS 0.29, INP 0.29.
Unlike the default set, these sets use more lenient FCP and LCP curves for mobile than for PC, reflecting the typically slower rendering on mobile devices. The same page therefore scores higher when measured as a mobile device: the typical corporate website above scores 66 as PC and 83 as mobile in the full set.
Warning
Scores from these sets are not directly comparable to the default one. Because the Lighthouse curves are much stricter for FCP and LCP, a page that meets all Web Vitals "good" thresholds scores 90 in the default set but only 74 in the full set — a page rated 🟢 Good by one set is rated 🟡 Needs improvement by the other. Compare scores only within the same metric set.
The following table shows the same websites as above, scored with every available metric set (PC, with CLS and INP values added):
| Scenario | CLS | INP | Default (3) | FCP + LCP | Full (5) | 4 (no INP) | 4 (no TTFB) |
|---|---|---|---|---|---|---|---|
| Fast CDN-served landing page | 0 | 0.03 s | 100 | 100 | 99 | 99 | 99 |
| Well-optimized news site | 0.05 | 0.12 s | 98 | 98 | 87 | 84 | 85 |
| Typical corporate website | 0.12 | 0.25 s | 82 | 81 | 66 | 61 | 63 |
| Heavy SPA (React/Angular) | 0.03 | 0.40 s | 72 | 61 | 62 | 62 | 56 |
| Ad-heavy media site | 0.35 | 0.80 s | 43 | 31 | 28 | 29 | 20 |
| Slow shared hosting blog | 0.20 | 0.60 s | 15 | 11 | 31 | 28 | 31 |
| Overloaded e-commerce site | 0.45 | 1.20 s | 7 | 5 | 10 | 10 | 10 |
| Broken/failing site | 1.50 | 3.00 s | 1 | 0 | 1 | 1 | 0 |
The slow shared hosting blog shows why the sets are not interchangeable: its paint times are bad but its CLS and INP values are acceptable, so the Lighthouse-based sets rate it around 30, while the default set — which only looks at loading performance — rates it at 15.