Skip to content

Commit fe96f3a

Browse files
ryansolidClaude via Cursor
andcommitted
chore(web,size): finish #3600 — useHead hydration carve-out in JSDoc, size caps re-measured over #3606
Rebased over #3605/#3606. `useHead`'s JSDoc names the documented-behavior carve-out: stylesheet reveal gating is skipped while `sharedConfig.hydrating` is true (hydration claims DOM the browser already painted; the server gated that paint), no FOUC introduced. Size caps re-measured on the rebased head (matches CI byte-for-byte): hydrating (no stores) 20,919 B (+36 over `next`'s 20,883) -> 20.95 KB; hydrating + stores 31,155 B (+10 over 31,145) -> 31.2 KB. `next` at ed60f05 already exceeds two caps — #3606 landed over #3605 unmeasured — so the observe tier (17,455 B, 0 B from this PR) is bumped to 17.5 KB with a note attributing it to #3606. `+ createStore` unchanged at 16,949. Co-authored-by: Claude via Cursor <[email protected]>
1 parent 5e540aa commit fe96f3a

2 files changed

Lines changed: 33 additions & 5 deletions

File tree

‎packages/web/src/client.ts‎

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1933,7 +1933,10 @@ function gateHeadResource(props) {
19331933
* Resolution is last-committed group per identity (reactive updates keep
19341934
* the registration's original commit position); disposal restores the
19351935
* previous winner. During hydration the server-flushed head state stays
1936-
* authoritative until hydration completes. See docs/head-management-rfc.md.
1936+
* authoritative until hydration completes. Stylesheet reveal gating is
1937+
* skipped while `sharedConfig.hydrating` is true: hydration claims DOM the
1938+
* browser already painted, and the server gated that paint — no FOUC is
1939+
* introduced. See docs/head-management-rfc.md.
19371940
*/
19381941
export function useHead(tag: HeadTag | HeadTag[] | (() => HeadTag | HeadTag[])): void;
19391942

@@ -1944,7 +1947,9 @@ export function useHead(tag: HeadTag | HeadTag[] | (() => HeadTag | HeadTag[])):
19441947
* after registration). Props values may be getters (reactive); updates keep
19451948
* the registration's original commit position. Disposal removes the
19461949
* registration and re-resolves (previous committed winner is restored).
1947-
* See docs/head-management-rfc.md.
1950+
* Stylesheet reveal gating is skipped while `sharedConfig.hydrating` is
1951+
* true: hydration claims DOM the browser already painted, and the server
1952+
* gated that paint — no FOUC is introduced. See docs/head-management-rfc.md.
19481953
*/
19491954
export function useHead(tags) {
19501955
initHeadRegistry();

‎scripts/size/.size-limit.js‎

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1201,7 +1201,17 @@ module.exports = [
12011201
// withHydrationGate creation flip; the quiet run reuses wrapFirstYield
12021202
// with the adopted value as its `quiet` parameter (+1 optional
12031203
// parameter, shared with the store adapter). 0 B in signals or web.
1204-
limit: "20.85 KB",
1204+
// Style-gated fragment resume (#3600, 2026-09-23): 20.85 -> 20.95 KB,
1205+
// measured at 20,919 B against `next`'s 20,883 (+36 B). Two parts.
1206+
// Inherited: `next` at ed60f054a already measures 20,883 (33 B over
1207+
// this cap) — #3606's `runDisposal` detach-before-run in the signals
1208+
// core landed over #3605's 20,843 without a bump (its PR CI ran on the
1209+
// pre-#3605 base). This PR: +36 B, solid only — the fragment ledger
1210+
// holds a boundary's resume until a `$dfs`-parked swap lands
1211+
// (`fragmentParked`, `whenRevealed`; `fragmentPending` reuses the parked
1212+
// test). 0 B in web: `waitAsset`'s `{ transparent: true }` and the
1213+
// hydrating skip in `gateHeadResource` are not in this fixture.
1214+
limit: "20.95 KB",
12051215
modifyEsbuildConfig
12061216
},
12071217
{
@@ -1473,7 +1483,13 @@ module.exports = [
14731483
// prior entry's brotli layout swing over this bundle reversing, so the
14741484
// two handoff PRs net +76 B here against +106 B no-stores). Solid only,
14751485
// in hydrateSignalLike (see the no-stores note).
1476-
limit: "31.15 KB",
1486+
// Style-gated fragment resume (#3600, 2026-09-23): 31.15 -> 31.2 KB,
1487+
// measured at 31,155 B against `next`'s 31,145 (+10 B; the same solid
1488+
// ledger source as the no-stores entry's +36 B, laid out differently by
1489+
// brotli over this larger bundle). `next`'s 31,145 already carries
1490+
// #3606's +11 B over #3605's 31,134, unbumped (see the no-stores note).
1491+
// 0 B in the signals core, the store engine, or web.
1492+
limit: "31.2 KB",
14771493
modifyEsbuildConfig
14781494
},
14791495
{
@@ -1793,7 +1809,14 @@ module.exports = [
17931809
// Fallback records time the display, not the swap (#3575 rebase): 17,402 B
17941810
// (+72 B) — the two boundaryFallback show sites pass the transaction the
17951811
// swap is staged in (`activeTransition`, or null for a lane swap).
1796-
limit: "17.45 KB",
1812+
// Inherited from `next` (#3606, recorded 2026-09-23 while landing #3600):
1813+
// 17.45 -> 17.50 KB, measured at 17,455 B on `next` at ed60f054a (17.43
1814+
// KB at #3605's a10d33ba3) and 17,455 with #3600 on top (0 B from
1815+
// #3600). #3606's `runDisposal`
1816+
// detach-before-run in the signals core landed over #3605 without a
1817+
// bump (its PR CI ran on the pre-#3605 base) and left this scenario 5 B
1818+
// over. Prod CSR is 15,819, byte-identical either way.
1819+
limit: "17.5 KB",
17971820
modifyEsbuildConfig: observeEsbuildConfig
17981821
},
17991822
{

0 commit comments

Comments
 (0)