Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

action is not tree-shakeable: read-only apps bundle the form path and signals' optimistic lanes (~3–4 KB br)

オープン
#655 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 1 日以内に返信

まだ誰も着手していません。

評価

難易度
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 — createRouterContext 3,029 · setupNativeEvents 2,398 (includes the form-action path) · query cache 1,814 · setupLinkClaims 1,486 · action glue ≈ 2,360 · scroll restoration 788 · browserHistory 594 · …
  • retained from @solidjs/signals: +8,583 — pulled by action: 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 / preload but not action bundles no form-submit interception, no submission state, and none of signals' lane machinery (verdictValue, dissolveLane, laneRead, isPending, latest absent from the bundle unless the app uses them itself).
  • An app that imports action behaves 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 + router scenario (or an examples/hackernews scenario) with and without import { 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分
マージ済み PR(30日)
36

環境構築

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

solidjs/solid-router のほかの issue

solidjs/solid-router の issue をすべて見る

似ている issue

TypeScript の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。