Skip to content

fix(web): send without a microtask when prepareRequest is sync (#3959) - #3990

Merged
ryansolid merged 2 commits into
nextfrom
fix/prepare-request-sync-3959
Oct 12, 2026
Merged

ryansolid merged 2 commits into
nextfrom
fix/prepare-request-sync-3959

Conversation

@ryansolid

Copy link
Copy Markdown
Member

Fixes #3959. Supersedes #3988 by @brenelz: this is his commit, unchanged and still authored by him, plus one follow-up commit for the test's types. His fork's branch can't be pushed from here.

Summary (from #3988)

With any prepareRequest hook configured, even init => init, a server-function read that hydration adopted was fetched again from the browser. Hydration runs an adopted source's compute once inside subFetch, which swaps window.fetch for a never-settling mock only for that synchronous call. createRequest always awaited the hook, so even a synchronous hook pushed send(base, init) one microtask later, after the real fetch was restored.

createRequest now awaits the hook's result only when it is a thenable. A synchronous hook sends in the calling tick. An async hook is still awaited, and the prepareRequest docs now say that an async hook makes hydrated reads fetch again.

Follow-up commit

test-types failed on #3988: test/hydration/prepare-request-hydration-3959.spec.tsx imported sharedConfig from "solid-js". It now imports it from "solid-js/internal", like the other hydration specs.

Verification

  • pnpm run test-types in packages/web: clean.
  • test/server/server-functions-extensions.spec.tsx (13) and test/hydration/prepare-request-hydration-3959.spec.tsx (2) pass. With server-functions/src/client.ts reverted to next, the new case in each fails.

Left open (from #3988)

A hydrated read whose arguments need the rich-argument codec still refetches, because of await serializeArguments(args), with or without a hook.

🤖 Generated with Claude Code

https://claude.ai/code/session_017PDt8Jv6uf5xRDsrux4UwF


Generated by Claude Code

@changeset-bot

changeset-bot Bot commented Oct 12, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 1bd35bb

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 12 packages
Name Type
@solidjs/web Patch
@solidjs/babel-plugin Patch
@solidjs/diagnostics Patch
@solidjs/element Patch
@solidjs/h Patch
@solidjs/html Patch
test-integration Patch
todos-server-example Patch
@solidjs/compiler Patch
@solidjs/signals Patch
solid-js Patch
@solidjs/universal Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-actions

Copy link
Copy Markdown

Size (brotli, eager entry chunk)

scenario head vs base minified vs base minified vs recorded cap lazy chunks (not counted)
signals: core floor (createSignal/Memo/Effect/Root/flush) 7.44 KB 0 B 0 B +31 B 7.45 KB ✅
signals: + createStore 14.71 KB 0 B 0 B +9 B 14.71 KB ✅
signals: + isPending/latest 9.69 KB 0 B 0 B −100 B 9.73 KB ✅
app: render + one signal (the simple-app floor) 9.91 KB 0 B 0 B −39 B 9.94 KB ✅
app: hydrating (no stores) with Show/For/Loading/Errored/lazy 17.70 KB 0 B 0 B −650 B 17.93 KB ✅ lazy-page.js 0.04 KB
app: hydrating + every store primitive family 29.08 KB 0 B 0 B −580 B 29.27 KB ✅ lazy-page.js 0.04 KB
app: CSR with Show/For/Loading/Errored/lazy 12.95 KB 0 B 0 B −47 B 12.98 KB ✅ lazy-page.js 0.04 KB
app: CSR, observe tier (same app on the observe artifacts) 14.56 KB 0 B 0 B −31 B 14.56 KB ⚠️ over by 5 B, 51 B minified headroom lazy-page.js 0.04 KB
app: CSR, observe tier + attribution engine enabled 28.86 KB 0 B 0 B −1 B 28.91 KB ✅ lazy-page.js 0.04 KB
app: compiled floor (one template, one text hole, one delegated click) 10.10 KB 0 B 0 B −57 B 10.13 KB ✅
app: compiled CSR (JSX todo app: spread/merge/omit, events, class/style, keyed For, Show, Loading + lazy, store) 25.42 KB 0 B 0 B −34 B 25.46 KB ✅ stats.js 0.18 KB
app: compiled hydrating (the same JSX todo app through hydrate(), compiled hydratable) 31.16 KB 0 B 0 B −656 B 31.39 KB ✅ stats.js 0.20 KB
frames: eager client consumer (frames client + transport, lazy codec) 11.43 KB 0 B 0 B 0 B 11.43 KB ✅
page: base server components (hydrating + dynamic + frames + sf reference) 33.86 KB −2 B (−0.0%) +36 B −2275 B 34.33 KB ✅ assets.js 0.78 KB, bind.js 1.83 KB, decode.js 6.23 KB, lazy-page.js 0.04 KB, regions.js 0.80 KB, trace.js 8.78 KB, wire.js 0.93 KB
page: live server components (base + live/GET + action + isPending/latest) 37.62 KB +46 B (+0.1%) +36 B −2404 B 38.15 KB ✅ assets.js 0.78 KB, bind.js 1.83 KB, decode.js 6.23 KB, lazy-page.js 0.04 KB, regions.js 0.80 KB, trace.js 8.77 KB, wire.js 0.93 KB
page: compiled base server components (the base page as JSX: templates with class/style/attributes/events, For/Show; no spread) 34.69 KB −35 B (−0.1%) +36 B −3440 B 35.66 KB ✅ assets.js 0.78 KB, bind.js 1.82 KB, decode.js 6.23 KB, regions.js 0.80 KB, sc-comments.js 0.20 KB, trace.js 8.74 KB, wire.js 0.93 KB
page: compiled live server components (the compiled base page + live/GET + action + isPending/latest) 40.34 KB +25 B (+0.1%) +36 B −3509 B 41.21 KB ✅ eager (counted): web.js 21.32 KB; assets.js 0.78 KB, bind.js 1.83 KB, decode.js 6.23 KB, regions.js 0.79 KB, sc-comments.js 0.19 KB, trace.js 8.72 KB, wire.js 0.93 KB
page: base + router (base page + @solidjs/router: createRouter, two routes, preload, useNavigate) 41.26 KB +50 B (+0.1%) +36 B −2281 B 41.79 KB ✅ assets.js 0.78 KB, bind.js 1.84 KB, decode.js 6.23 KB, lazy-page.js 0.04 KB, regions.js 0.80 KB, server.js 1.02 KB, serverForms.js 3.59 KB, trace.js 8.79 KB, wire.js 0.94 KB
page: live + router (live page + @solidjs/router: createRouter, two routes, preload, useNavigate) 46.95 KB −1 B (−0.0%) +36 B −2350 B 47.49 KB ✅ eager (counted): client.js 27.47 KB; assets.js 0.78 KB, bind.js 1.85 KB, decode.js 6.23 KB, lazy-page.js 0.04 KB, regions.js 0.81 KB, server.js 1.02 KB, serverForms.js 3.30 KB, trace.js 8.75 KB, wire.js 0.94 KB
server: floor (getRequestEvent + isServer) 1.33 KB 0 B 0 B 0 B 1.34 KB ✅
server: renderToString (the server-render floor) 20.40 KB 0 B 0 B +4 B 20.42 KB ✅

⚠️ Over the brotli cap within the minified allowance (passes)

  • app: CSR, observe tier (same app on the observe artifacts): over brotli cap by 5 B; minified 41,274 B vs 41,305 B recorded with the cap (−31 B) — 51 B of the 20 B minified allowance left; +0 B minified over this PR's base

Bundled with Rolldown (what Vite ships), brotli q11, decimal KB. A scenario fails only when it is over its brotli cap and its minified size is more than 20 B over the minified recorded with the cap; over the cap within that allowance is brotli layout noise and passes with a warning. Caps and their recorded minified in scripts/size/scenarios.js; the floor and page caps in floor-caps.json are frozen (lower only, or Size-Exception: in the PR body). npm run ratchet lowers caps per RC; it never raises one (scripts/size/README.md).

@coveralls

Copy link
Copy Markdown

Coverage Report for CI Build 38273324407

Coverage remained the same at 77.429%

Details

  • Coverage remained the same as the base build.
  • Patch coverage: No coverable lines changed in this PR.
  • No coverage regressions found.

Uncovered Changes

No uncovered changes found.

Coverage Regressions

No coverage regressions found.


Coverage Stats

Coverage Status
Relevant Lines: 1321
Covered Lines: 1079
Line Coverage: 81.68%
Relevant Branches: 1036
Covered Branches: 746
Branch Coverage: 72.01%
Branches in Coverage %: Yes
Coverage Strength: 27.16 hits per line

💛 - Coveralls

@ryansolid
ryansolid deleted the fix/prepare-request-sync-3959 branch October 12, 2026 16:01
@codspeed

codspeed Bot commented Oct 12, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

⚠️ 2 benchmarks spent significant time in system calls

System calls cannot be consistently instrumented, so they are not included in the measure, which understates the real cost. Please switch to the Walltime instrument to accurately measure system calls.

Measurement and system calls

✅ 195 untouched benchmarks


Comparing fix/prepare-request-sync-3959 (1bd35bb) with next (b460640)

Open in CodSpeed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants