action is not tree-shakeable: read-only apps bundle the form path and signals' optimistic lanes (~3–4 KB br)
维护者通常 1 天内回复
还没有人认领这个 Issue。
评估
- 难度
- 4/5
- 预计耗时
- 3-5 天
- 新手友好度
- 45/100
- Issue 类型
- 重构
- 描述清晰度
- 描述清楚
- 活跃度
- 活跃
- 技术栈
- typescript
- 领域
- performance
调研方向
Start from the router's source for setupNativeEvents and createRouterContext (form-submit interception and submission state), plus the module exporting action from @solidjs/router. Map which symbols pull verdictValue, dissolveLane, laneRead, isPending and latest from @solidjs/signals, then design the import-time registration seam so importing action installs them. Done means: a bundle of examples/hackernews without import { action } drops those symbols (~3–4 KB brotli, measured via solidjs/solid's scripts/size harness), while a bundle with action behaves identically — form interception, submissions and optimistic state unchanged.
由索引模型根据 Issue 内容生成。
描述
Summary
A read-only app (no forms, no mutations — examples/hackernews in solidjs/solid is the canonical case) still bundles the router's action machinery: the form-submit interception in setupNativeEvents, the submission state wired in createRouterContext, action's own glue, and — through it — the optimistic-lane machinery from @solidjs/signals. None of it is reachable from the app's code, but the router core references it statically, so tree-shaking cannot remove it.
Proposal: make action self-installing. The core keeps a tiny seam (a submit hook + a submissions slot); import { action } from "@solidjs/router" registers the form path and the lane-backed submission state into that seam at import time. An app that never imports action bundles none of it. No laziness, no async — plain import-driven tree-shaking, the same shape Solid uses for its own opt-in features.
Measurements
Taken with solidjs/solid's size harness (scripts/size, Rolldown bundle, brotli) on @solidjs/[email protected] against solid-js / @solidjs/web 2.0.0-rc.13 — see solidjs/solid#3838 (page: base + router scenario). Local macOS / Node 26; minified bytes are exact, brotli ±tens of bytes vs Linux CI.
| minified | brotli | |
|---|---|---|
| router standalone (solid/web external) | 32,430 | 11,216 |
| router's marginal cost on a server-component page | +38,779 | +12,137 |
Of the +38,779 min marginal:
- router's own code: 28,008 —
createRouterContext3,029 ·setupNativeEvents2,398 (includes the form-action path) ·querycache 1,814 ·setupLinkClaims1,486 ·actionglue ≈ 2,360 · scroll restoration 788 ·browserHistory594 · … - retained from
@solidjs/signals: +8,583 — pulled byaction: the optimistic lanes (verdictValue,dissolveLane,laneRead),isPending/latest,createEffect,onSettled - retained from the server-function client: +1,188 (
GET/decodeResponse—query's, legitimately) - retained from
@solidjs/web: +1,137 (takeHydrationValue,registerElementClaim) - retained from
solid-js: +364
For a read-only app the action-attributable part is roughly the action glue + the form path inside setupNativeEvents + the signals lane machinery — on the order of 11–13 K minified, ≈ 3–4 KB brotli, carried for a feature the app never imports.
For scale: the router's standalone 11.2 KB br is larger than the entire eager frames (server-components) client after this week's size pass (10.9 KB), and about two-thirds of the whole solid-js + @solidjs/web hydrating runtime.
What "done" looks like
- An app importing
Router/ routes /A/useNavigate/query/preloadbut notactionbundles no form-submit interception, no submission state, and none of signals' lane machinery (verdictValue,dissolveLane,laneRead,isPending,latestabsent from the bundle unless the app uses them itself). - An app that imports
actionbehaves exactly as today (form interception, submissions, optimistic state) — the registration is at import time, synchronous, no behaviour change. - Measurable: a variant of solidjs/solid's
page: base + routerscenario (or anexamples/hackernewsscenario) with and withoutimport { action }; expected delta ≈ 3–4 KB brotli on the read-only variant.
Secondary candidates (same shape, smaller)
Scroll restoration (788 min) and the form path in setupNativeEvents could follow the same import-driven pattern. query / preload is the read side and should stay in the core.
Method, for reproduction
The attribution came from solidjs/solid's scripts/size/attribute.mjs over the harness bundle (per-function minified bytes; module-level reachability via the bundler's graph). Removing action's reach is measurable on an edited copy of the router's dist/ through the same bundler before any source change — happy to share the scripts.
- 主要语言
- TypeScript
- 星标
- 1.3k
- 派生
- 182
- 平均合并
- 19 小时 2 分钟
- 30 天内合并 PR
- 36
环境准备
- 没有 Dockerfile 或 Docker Compose 文件
- 没有 Pull Request 模板
- 阅读贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
solidjs/solid-router 的其他 Issue
-
难度 4/5 3-5 天 新手友好度 52/100
solidjs/solid-router#654 · 1 条评论 ·
维护者通常 1 天内回复
-
bug
难度 4/5 3-5 天 新手友好度 52/100
solidjs/solid-router#643 · 1 条评论 ·
维护者通常 1 天内回复
-
<A> costs ~6us of server CPU per instance during SSR (20x a plain <a>), mostly mergeProps/splitProps可能已有人在做 @birkskyum 于 59 天前认领。 未关闭
难度 4/5 3-5 天 新手友好度 55/100
solidjs/solid-router#583 ·
维护者通常 1 天内回复
-
enhancement
难度 5/5 一周以上 新手友好度 35/100
solidjs/solid-router#569 · 3 条评论 ·
维护者通常 1 天内回复
-
enhancement
难度 3/5 1-2 天 新手友好度 38/100
solidjs/solid-router#518 · 2 条评论 ·
维护者通常 1 天内回复
查看 solidjs/solid-router 的全部 Issue
相似的 Issue
-
[bug] diagnostics.dumpBody:Buffer 形态请求(透传 lane)跳过 dumps/ 落盘,仅留 raw/-unknown-可能已有人在做 @ranxianglei 今天认领。 未关闭
难度 2/5 1-3 小时 新手友好度 62/100
ranxianglei/billion-context#2421 · 2 条评论 ·
维护者通常 1 天内回复
-
pending triage
难度 2/5 1-3 小时 新手友好度 76/100
nuxt/test-utils#1842 ·
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 85/100
MoonshotAI/kimi-code#4146 ·
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 85/100
farbenmeer/tapi#531 ·
-
难度 2/5 1-3 小时 新手友好度 85/100
维护者通常 1 天内回复