Repository navigation
http: fixes and improvements for HTTP, SSR and hydration #351
Copy link
Copy link
Closed
Labels
bugSomething is broken or shows wrong dataSomething is broken or shows wrong datafeatureA feature request or a pull request that adds oneA feature request or a pull request that adds one
Description
Context
Fixes and improvements from a code audit of http, ssr and hydration, done in October 2026. Roadmap work lives in #340, #341, #342 and #343. Items marked (to confirm) were not reproduced; check them before fixing.
Problems
Medium
- compression breaks SSR sniffing and state edits: when
compression()is mounted afterssrMiddleware, it wrapsres.writeoutside our wrapper, so the middleware sees gzip or brotli bytes. The render mode sniff then reads garbage, andbufferForEditsjoins the chunks as UTF-8, can't find the TransferState script and only notes "could not edit". Nothing checkscontent-encoding. Checkres.getHeader('content-encoding'), skip the sniff and the edit when it is set, and say "mount ssrMiddleware after compression" in the override note and the request detail (packages/devtools/src/ssr-middleware.ts:156-162,ssr-middleware.ts:180-245). - network inspector page is too big:
network-inspector.tsis 2709 lines, with about 860 lines of inline CSS and the SSR requests, timeline, rules, overrides, hydration and payload sections in one class. Split it into child components (SSR requests, HTTP timeline, rule form, SSR override form, hydration card, payload tree) with a shared store service, and move the styles to a.cssfile (app/src/pages/network-inspector.ts:1221,network-inspector.ts:2078).
Low
- client cache check disagrees with the server one:
transferCacheEligibleignorescredentials: 'include' | 'same-origin', whichcacheSkipReasontreats as a skip, and can't mirrorincludePostRequests,includeRequestsWithAuthHeadersorincludeHeaders. Share one predicate between both files, and letwithPangular({ transferCache })take the app'sHttpTransferCacheOptions(packages/devtools/src/http.ts:170-181,packages/devtools/src/http-cache-reason.ts:24-44). - server "cache hit" is misleading: on the server any synchronous, unmocked response gets
cacheHit: true, andlist-http-callsprints "cache hit", although Angular's transfer cache never replays on the server. SetcacheHitto false on the server and keepcacheStoredas the server signal (packages/devtools/src/http.ts:292,packages/devtools/src/rpc/http-tools.ts:43). - console patch moves every call site:
captureHydrationWarningsreplacesconsole.warnandconsole.errorfor good, so Chrome shows every warning and error as coming fromhttp.ts. Add the package output tox_google_ignoreListin the published source maps, and keep a way to undo the patch. phase 3 of 4: a shell you live in #342 plans one console tap for all three patches; this fix should land with it (packages/devtools/src/http.ts:348-366). - hydration scan goes stale: after 3 scans the scanner returns its cache while the counter key is unchanged. When
ngDevModeis the booleantrue, the key is always'', so mismatches from later incremental hydration never show. Each scan also walks up to 50k nodes withSHOW_ALL. Add a MutationObserver flag or a timestamp to the key, walk only elements, text and comments, and rescan after@defer (hydrate on ...)triggers (packages/devtools/src/http-overlay.ts:27-38,packages/devtools/src/http-hydration.ts:45-48). - duplicated, unanchored URL glob:
globMatchis copied in two files. A pattern matches as a substring anywhere, so/apialso matches/apiv2and URLs whose query string contains/api, with no way to anchor it. Extract one helper, support^to anchor at the path start (or match the path only, with an opt-in for the query), and show a live match count in the rule form (packages/devtools/src/http-rules.ts:116,packages/devtools/src/ssr-overrides.ts:61).
Improvements
- Payload tab extras: per-key size bars, a payload budget warning (for example over 100 KB, or the largest keys), duplicate keys or the same URL stored twice, and a "refetch this key" action (
packages/devtools/src/http-payload.ts,app/src/pages/network-inspector.ts). - Hydration mismatch diff: show expected and actual side by side, highlight the node through the overlay and jump to the owning component in the component tree (
packages/devtools/src/http-hydration.ts,app/src/pages/network-inspector.ts). - Duplicate and waterfall lint for client calls: the same GET fired N times in a window, sequential calls that could run in parallel, and calls after the stable point that re-request transfer-cache data, plus a
lint-httpagent tool listed inconfig.ts(packages/devtools/src/rpc/http-tools.ts,packages/devtools/src/config.ts). - "Copy as fetch" and "Copy as cURL", and replay of a recorded call, with redacted headers (
app/src/pages/network-inspector.ts,packages/devtools/src/http-redact.ts). - HAR export of a page session, client and server calls plus Server-Timing, with redaction applied (
app/src/pages/network-inspector.ts,packages/devtools/src/http-redact.ts). - Server-Timing entry for each server HttpClient call (
fetch-<n>;desc=url;dur=), so Chrome's own Network timing tab shows the breakdown (packages/devtools/src/ssr-middleware.ts,packages/devtools/src/http.ts). - Rule presets: "offline" (status 0 network error through an
ErrorEvent-basedHttpErrorResponse), "slow 3G" as a global delay, and a flaky mode that fails at a set rate (packages/devtools/src/http-rules.ts,packages/devtools/src/http.ts). - Label calls made by
httpResourceandresource(), and by@deferchunks, so users see which resource issued a request (packages/devtools/src/http.ts). - Record native
fetchcalls (Analog$fetch, third-party SDKs, server fetches in resolvers) in dev on both sides, tagged with side and request id (packages/devtools/src/http.ts,packages/devtools/src/http-rules.ts).
Already tracked elsewhere
- SSR tracing for web-standard
Request/Responsehandlers (Hono, h3, Nitro/Analog): phase 4 of 4: deeper diagnosis #343. - Agent tools for TransferState, SSR overrides and hydration explainers: phase 4 of 4: deeper diagnosis #343.
- Redacted request and response headers on client calls, and a network waterfall: phase 4 of 4: deeper diagnosis #343.
Generated by Claude Code
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
bugSomething is broken or shows wrong dataSomething is broken or shows wrong datafeatureA feature request or a pull request that adds oneA feature request or a pull request that adds one
Activity
fix: audit findings for components, injectors, signals, pipes and HTTP (