|
| 1 | +--- |
| 2 | +layout: post |
| 3 | +title: "Web-Perf Wednesday 005 – RUM Needs More Than a Percentile" |
| 4 | +date: 2026-08-19 12:00:00 +0100 |
| 5 | +categories: Web Development |
| 6 | +main: "" |
| 7 | +meta: "LUX Sidecar adds context to RUM, while browser-tool fixes show why measurement conditions and small debugging details matter." |
| 8 | +--- |
| 9 | + |
| 10 | +There’s more to work with than there was [last |
| 11 | +week](/2026/08/web-perf-wednesday-004-a-quiet-week-is-time-to-investigate/), |
| 12 | +although the useful changes are less about new headline metrics than the context |
| 13 | +around them. I released a small SpeedCurve companion that keeps more of that |
| 14 | +context alongside RUM data, WebKit fixed a developer-tool setting that could |
| 15 | +change the request under inspection, and browser work made two small but useful |
| 16 | +parts of debugging and delivery less awkward. This week is really about making |
| 17 | +the evidence easier to explain. |
| 18 | + |
| 19 | +## RUM Needs Context It Can Keep |
| 20 | + |
| 21 | +I released [LUX |
| 22 | +Sidecar](/2026/08/introducing-lux-sidecar/) this week: a small, independent |
| 23 | +plugin that runs alongside SpeedCurve’s LUX agent and sends extra custom data |
| 24 | +through its [`LUX.addData()` |
| 25 | +API](https://support.speedcurve.com/docs/rum-js-api). It needs an existing |
| 26 | +SpeedCurve RUM account and doesn’t replace the normal LUX snippet; its job is to |
| 27 | +retain some of the browser and navigation context that helps explain the |
| 28 | +measurements SpeedCurve already collects. |
| 29 | + |
| 30 | +That context includes the browser’s reported round-trip time and downlink, |
| 31 | +cache state, protocol, content encoding, service-worker involvement, bfcache or |
| 32 | +prerender use, and a handful of additional timings such as Time to Last Byte |
| 33 | +(TTLB) and Unattributed Navigation Overhead (UNO). Browser support varies, so |
| 34 | +Sidecar feature-detects each value and omits what isn’t available rather than |
| 35 | +turning missing evidence into a misleading zero. |
| 36 | + |
| 37 | +The distinction between metrics and dimensions is particularly useful here. |
| 38 | +TTLB and UNO are values we can chart; cache state, protocol, and service-worker |
| 39 | +involvement describe the page views we want to compare. An origin-level p75 can |
| 40 | +tell us that performance moved, but it can’t tell us whether the slower visits |
| 41 | +crossed a high-latency connection, transferred an uncached document, or waited |
| 42 | +for a service worker to start. |
| 43 | + |
| 44 | +None of those dimensions supplies a diagnosis on its own. A high reported RTT |
| 45 | +doesn’t absolve the application, a zero-byte transfer isn’t a complete cache |
| 46 | +taxonomy, and `nextHopProtocol` may describe a connection to an intermediary |
| 47 | +rather than the origin. Their value is in turning one broad population into |
| 48 | +comparisons we can test. If TTLB rose only for uncached documents, or TTFB looks |
| 49 | +poor mainly among high-RTT visits, we have a much better place to begin. |
| 50 | + |
| 51 | +For teams already using SpeedCurve, the practical work is to create the custom |
| 52 | +metrics and dimensions with the correct types, deploy Sidecar after LUX, and |
| 53 | +record the script version with release annotations. Start with a question the |
| 54 | +current dashboard can’t answer rather than enabling every value because it is |
| 55 | +available. A careful [RUM measurement review](/consultancy/) should add enough |
| 56 | +context to separate useful cohorts while keeping the dashboard comprehensible |
| 57 | +to the people who need to act on it. |
| 58 | + |
| 59 | +The broader point applies well beyond this plugin. Performance data is rarely |
| 60 | +short of numbers; it is usually short of the delivery, device, navigation, and |
| 61 | +release context that explains why those numbers differ. Collecting that context |
| 62 | +at the same time as the page view is considerably easier than trying to |
| 63 | +reconstruct it once an aggregate graph has moved. |
| 64 | + |
| 65 | +## Safari’s ‘Ignore Cache’ Was Changing Requests |
| 66 | + |
| 67 | +[Safari Technology Preview 250](https://webkit.org/blog/18191/release-notes-for-safari-technology-preview-250/) |
| 68 | +fixed Web Inspector’s <cite>Ignore Cache</cite> setting overwriting a |
| 69 | +page-authored `Cache-Control` request header. As I [explained in more |
| 70 | +detail](/2026/08/when-safaris-ignore-cache-ignored-cache-control/), WebKit could |
| 71 | +bypass its local resource cache _and_ replace the header the application meant |
| 72 | +to send with `no-cache`. |
| 73 | + |
| 74 | +The fix preserves an existing request header while retaining WebKit’s internal |
| 75 | +cache-bypass policy. That matters when an origin, CDN, or shared cache responds |
| 76 | +differently to `no-cache`: the debugging condition could otherwise change the |
| 77 | +behaviour being investigated. The release note establishes the fix in |
| 78 | +Technology Preview 250, not a particular stable Safari version, so record the |
| 79 | +browser and Inspector settings in caching tests and keep cold-, warm-, and |
| 80 | +disabled-cache measurements separate. A [cache-behaviour |
| 81 | +investigation](/performance-audits/) needs the request that the application |
| 82 | +actually made. |
| 83 | + |
| 84 | +## DevTools’ Request Numbers Move Left |
| 85 | + |
| 86 | +In June, I [reported that Chrome DevTools’ optional ‘Request #’ |
| 87 | +column](https://issues.chromium.org/issues/525848667) appeared after ‘Name’ in |
| 88 | +the Network panel even though columns couldn’t be rearranged, and recommended |
| 89 | +pinning the index first. Chromium reproduced the behaviour, the DevTools team |
| 90 | +agreed with the change, and the linked implementation was merged on 20 July. |
| 91 | + |
| 92 | +The issue’s verifier says the fix worked in Canary 152.0.7962.0, where enabling |
| 93 | +the column put it in position one. However, the public issue is still marked |
| 94 | +‘In Progress (Accepted)’, and the evidence does not establish a stable release, |
| 95 | +so it would be premature to call this shipped generally. It is a small change, |
| 96 | +but a useful one: request numbers are much easier to scan and discuss when the |
| 97 | +index sits at the edge of the table rather than after a wider column such as |
| 98 | +‘Name’. |
| 99 | + |
| 100 | +## Safari Begins Streaming Fetch Uploads |
| 101 | + |
| 102 | +Technology Preview 250 also adds initial support for using a `ReadableStream` |
| 103 | +as a `fetch()` request body, together with the required `duplex` option on |
| 104 | +`Request`. This could eventually let generated or large request bodies begin |
| 105 | +uploading as their data becomes available instead of waiting for the complete |
| 106 | +body. |
| 107 | + |
| 108 | +‘Initial’ is doing important work. The [underlying WebKit |
| 109 | +change](https://github.com/WebKit/WebKit/commit/0a676123bd679af5b6d5f7c9be6e967b4437fab3) |
| 110 | +describes follow-up work and limitations around service workers and networking |
| 111 | +backends. Treat this as an interoperability signal to test, not a stable |
| 112 | +cross-browser foundation: exercise the real protocol, redirects, cancellation, |
| 113 | +server behaviour, and any service-worker path before changing an upload |
| 114 | +architecture. |
| 115 | + |
| 116 | +## Need Help Adding Context to Your RUM? |
| 117 | + |
| 118 | +If a RUM graph tells you that performance changed but not why, I can help work |
| 119 | +out which navigation, delivery, device, and release dimensions would make the |
| 120 | +data useful. That may mean adding carefully chosen context, checking whether a |
| 121 | +debugging tool altered the conditions, or designing comparisons that separate a |
| 122 | +real product regression from a change in the population. |
| 123 | + |
| 124 | +The aim isn’t a dashboard with more fields; it is evidence that leads to a |
| 125 | +decision with less guesswork. If your percentiles are accurate but still leave |
| 126 | +the team arguing about the cause, [get in touch](/contact/). |
| 127 | + |
| 128 | +{% include web-perf-wednesdays.md %} |
0 commit comments