Avatar for the solidjs user
solidjs
solid
BlogDocsChangelog

Performance History

Latest Results

Merge pull request #3495 from solidjs/fix/staged-reporter-deps fix(signals): reporter liveness reads this pass's deps; a dropped dep retires the reporter (fuzzer #3446 P1, remaining forms)
next
24 minutes ago
perf(signals,web): omit over a merge holds the merge record — one record per layer, one-pass owners walk for ssrElement An omit over a merge flattened at construction: one OmitView plus one combined hidden-key list per flattened leaf, and the next merge() copied those entries into its arrays — on a Kobalte-shaped chain (defaults + omit + spread, four layers) ~19 records and as many list copies per element, the largest allocation of the render. #3487 tried to make those copies cheaper and could not beat slice+push on instruction count; this does not make them. The omit now holds the MergeView record itself (new source kind SOURCE_MERGE) and is one record whatever the merge's leaf count; a later merge() carries it as one entry, a later omit() folds into it. Nothing on the way is a trap: sourceKeys/sourceHas/sourceGet, descriptors, hasStaticKeys and the tables recurse into the record by function call — the property #3454 established (consumers read the leaves, never through a proxy) is kept, the per-leaf copies are not. Three things had to hold for it to pay, each found by measurement: - one walk per read: a nested entry answers presence and value together (MISSING sentinel), not has-then-get per level; - a record reached through an outer view counts no reads toward its own table threshold, and the outer view's table is collected in one pass over the leaves (collectTable) — not one table per layer; - sourceOwners(source, keys, owners): every key of a plain object, store or view in merged order with its owning object, one pass. ssrElement collects any non-plain spread (a view, a store, the array form with one among them) this way and reads owners[i][keys[i]] — the flat form's read cost without its construction cost. pushEntry is gone. An omit's $SOURCES answers nothing now; consumers reach the record via viewOf. Reads through an omit no longer count on the inner merge: the view that was asked decides for the tree. Measured against next (interleaved, min of N, quiet machine): tier-1 polymorphic-chain SSR −12% bytes/row, −2…−6% time across interp, Sparkplug, Maglev, TurboFan; props-chain build −6…−65%, build+consume −7…−31% by depth and tier; omit/merge micro-suite flat or better in every shape; yak-bench SSR all-primitives lane +7% geomean, +20–36% on the composition cases, which reach parity with yak's hand-rolled runtime. Co-authored-by: Claude via Cursor <noreply@cursor.com> Co-authored-by: Cursor <cursoragent@cursor.com>
perf/omit-nested-record
27 minutes ago
fix(store): preserve shallow leaves and sequence hybrid hydration
Monkeylordz:codex/fix-shallow-store-hydration
5 hours ago
fix(signals,solid): reserve `_parent` from property mangling — the second cross-package owner field; retire the wall-clock tripwires Signals' prod/observe artifacts rename every `_` field but `_name`; the dev artifact the suites run against is unmangled. Two `_parent` reads crossed the package boundary and only worked in dev: solid-js's client hydration walked `owner._parent` to mark the snapshot root (prod marked the current owner instead), and the core's `ownerPath`/`isExcluded` walks over server owners (`ownerPath` shimmed by `located()`, now removed; `OBSERVE.exclude` a silent no-op for a server owner outside dev). `_parent` is reserved alongside `_name`; ~40 B brotli on the prod app scenarios, two caps bumped. Pinned from both ends: solid's cross-package-fields spec checks the reserved fields survive mangling and scans every built client artifact for a signals `_` field not on the list; web's server-owner-walks spec runs `ownerPath` and `OBSERVE.exclude` over server owners against the built observe and development artifacts. Timing tripwires that flaked under parallel CI load: heap-mark re-measures a round over the cap; attribution-navigation asserts against the wait actually taken rather than a timer's nominal 10ms; both shell-gating specs prove ordering by settling gates by hand (shell-gating-harness.ts) instead of wall-clock deltas against timers. RFC 08 gains "Values in records — the PII surface": every record and finding field that carries user data, `data.error` on the server error findings included, for exporters that leave the process. Co-authored-by: Claude via Cursor <noreply@cursor.com> Co-authored-by: Cursor <cursoragent@cursor.com>
cross-package-fields
7 hours ago
perf(signals,web): omit over a merge holds the merge record — one record per layer, one-pass owners walk for ssrElement An omit over a merge flattened at construction: one OmitView plus one combined hidden-key list per flattened leaf, and the next merge() copied those entries into its arrays — on a Kobalte-shaped chain (defaults + omit + spread, four layers) ~19 records and as many list copies per element, the largest allocation of the render. #3487 tried to make those copies cheaper and could not beat slice+push on instruction count; this does not make them. The omit now holds the MergeView record itself (new source kind SOURCE_MERGE) and is one record whatever the merge's leaf count; a later merge() carries it as one entry, a later omit() folds into it. Nothing on the way is a trap: sourceKeys/sourceHas/sourceGet, descriptors, hasStaticKeys and the tables recurse into the record by function call — the property #3454 established (consumers read the leaves, never through a proxy) is kept, the per-leaf copies are not. Three things had to hold for it to pay, each found by measurement: - one walk per read: a nested entry answers presence and value together (MISSING sentinel), not has-then-get per level; - a record reached through an outer view counts no reads toward its own table threshold, and the outer view's table is collected in one pass over the leaves (collectTable) — not one table per layer; - sourceOwners(source, keys, owners): every key of a plain object, store or view in merged order with its owning object, one pass. ssrElement collects any non-plain spread (a view, a store, the array form with one among them) this way and reads owners[i][keys[i]] — the flat form's read cost without its construction cost. pushEntry is gone. An omit's $SOURCES answers nothing now; consumers reach the record via viewOf. Reads through an omit no longer count on the inner merge: the view that was asked decides for the tree. Measured against next (interleaved, min of N, quiet machine): tier-1 polymorphic-chain SSR −12% bytes/row, −2…−6% time across interp, Sparkplug, Maglev, TurboFan; props-chain build −6…−65%, build+consume −7…−31% by depth and tier; omit/merge micro-suite flat or better in every shape; yak-bench SSR all-primitives lane +7% geomean, +20–36% on the composition cases, which reach parity with yak's hand-rolled runtime. Co-authored-by: Claude via Cursor <noreply@cursor.com> Co-authored-by: Cursor <cursoragent@cursor.com>
perf/omit-nested-record
7 hours ago

Latest Branches

CodSpeed Performance Gauge
-3%
perf(signals,web): omit over a merge holds the merge record — one record per layer, one-pass owners walk for ssrElement#3497
8 hours ago
328580f
perf/omit-nested-record
CodSpeed Performance Gauge
+17%
fix(signals): reporter liveness reads this pass's deps; a dropped dep retires the reporter (fuzzer #3446 P1, remaining forms)#3495
1 hour ago
0e80ca7
fix/staged-reporter-deps
CodSpeed Performance Gauge
-21%
5 hours ago
c4ba6c7
Monkeylordz:codex/fix-shallow-store-hydration
© 2026 CodSpeed Technology
Home Terms Privacy Docs