cloudflare / cloudflare/telescope
Aggressive page.route disabling HTTP Cache
- Dominant language
- TypeScript
- Stars
- 305
- Forks
- 36
- PR merge metrics
- No merged PRs in 30d
Description
## Describe the bug
From Playwright's own [docs](https://playwright.dev/docs/api/class-page#page-route), calling page.route() disables the HTTP Cache. Specifically for Early Hints, this causes the browser to perform the request again instead of using the hinted resource.
There are two independent causes that we've found:
1. `overrideHost` defaults to `{}`, but the truthy object causes Telescope to
register a route using an empty regular expression, which matches every URL.
2. Telescope unconditionally registers `page.route('**/*')` to inject a unique
`x-telescope-id` header into every regular request.
The ID is useful for exact correlation between Playwright request timings, HAR
entries, and Chromium CDP priorities. Removing it silently would break an
existing documented behavior, so a backward-compatible cache-preserving mode
seems preferable.
## Current code paths
### Empty `overrideHost` registers a broad route
`overrideHost` defaults to an empty object:
The empty object is truthy, so `setupHostOverrides()` runs:
With no keys, the implementation evaluates the equivalent of:
```ts
Object.keys({}); // []
[].join("|"); // ''
new RegExp(""); // matches every URL
```
It then passes that expression to `page.route()`:
Current Telescope also registers a catch-all route to inject
`x-telescope-id`:
## Telescope info
Please include the following information about your environment:
**Telescope version**: 1.20
**Node version**: v26.0.0
**Operating system version**: Macos Tahoe 26.5
**Google Chrome**: 150.0.7871.129
## Steps to reproduce
1. Confirm that your connection receives the `103`:
```bash
curl --http2 -sS -D - -o /dev/null \
https://theme-horizon-demo.myshopify.com/
```
The output should contain `HTTP/2 103` followed by `HTTP/2 200`. If it does
not, a network intermediary may be removing informational responses.
2. Run Telescope with its default settings:
```bash
npx --yes @cloudflare/telescope@1.2.0 \
-u https://theme-horizon-demo.myshopify.com/
```
3. Copy the test ID printed by Telescope, then inspect the timing of the `103`,
the final response, and one hinted stylesheet:
```bash
TEST_ID='paste-the-Test-ID-here'
jq '.navigationTiming | {
earlyHints: .firstInterimResponseStart,
finalHeaders: .finalResponseHeadersStart
}' "results/$TEST_ID/metrics.json"
jq '.[] | select(.name | contains("/base.css")) | {
startTime,
transferSize
}' "results/$TEST_ID/resources.json"
```
## Expected results
The hinted stylesheet should start before the final response headers arrive.
Chrome should then reuse it when the final HTML references it.
## Observed results
Chrome received the `103` before the final response headers:
```text
earlyHints: 152.1 ms
finalHeaders: 236.7 ms
```
However, the hinted `base.css` request starts afterward and performs a network
transfer:
```text
startTime: 239.5 ms
transferSize: 13514 bytes //transferSize is non-zero due to HTTP Cache being disabled
```
Contributor guide
Research direction
Start by reading packages/telescope/src/defaultOptions.ts and the setupHostOverrides() and catch-all route paths in packages/telescope/src/testRunner.ts. Reproduce the default-settings run, then inspect metrics.json and resources.json as described to confirm the Early Hints request is transferred. Done means the documented x-telescope-id correlation remains available while default routing no longer prevents the hinted resource from using HTTP Cache.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- playwright, typescript
- Domain
- performance, testing
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100