Skip to content

feat(dev): support on-demand SSR imports - #158

Open
ScriptedAlchemy wants to merge 19 commits into
mainfrom
codex/ssr-lazy-compilation
Open

ScriptedAlchemy wants to merge 19 commits into
mainfrom
codex/ssr-lazy-compilation

Conversation

@ScriptedAlchemy

@ScriptedAlchemy ScriptedAlchemy commented Oct 6, 2026 •

Copy link
Copy Markdown
Collaborator

Why

For issue #155, compile optional SSR imports on demand and keep the original request suspended through activation. A second tab must not reset an unrelated page.

What changed

  • Add opt-in unstableServerLazyCompilation for classic SSR, with eager entries and a retained native runtime in both module formats.
  • Gate application imports until trusted activation receipts, graph checks, native HMR, and the settled Web manifest commit together. Genuine edits retain HMR, data revalidation, and CSS updates.
  • Add native failure and concurrency regressions plus a rerunnable two-tab React.lazy fixture and browser verifier.

Scope

This branch pins the Rsbuild preview and a published Rspack canary with matching native bindings. The canary combines watch origins with the lazy HMR identity fix, replacing the local patch. The upstream PRs remain unmerged.

The feature defaults to false. RSC, federation, custom lazy clients or backends, and cold imports before initial publication are unsupported. After a rejected activation, cold imports can require a server source edit to recover. ESM caches persist until process restart. Recovery preserves accepted exports. Arbitrary application side effects can persist.

Blast Radius

The controller gains lifecycle branches to preserve one session and generation owner. Structural review still flags controller complexity and recent churn. No metric acknowledgment or baseline reset hides these findings.

Verification

  • pnpm build, pnpm typecheck, pnpm test:core, and pnpm test:package-interop pass. Core has 899 passing cases, including 36 real native CJS/ESM cases. macOS uses a physical TMPDIR as documented.
  • The browser verifier passes with 100 and 1000 React.lazy leaves, including a matched stock/candidate run at 1000 leaves. Stock compiles 1000 server leaves at startup; the candidate compiles zero, then one for the original SSR request. The unrelated tab retains its text and document without activation-induced HDR or reload.
  • Browser checks cover loader, action, dependency, route meta, and CSS edits. Native checks cover delayed apply, overlapping imports, Web failure, source supersession, recovery, and shutdown. Raw latency comparisons are inconclusive under host load; no speedup is claimed.

Native serverBundles coverage verifies activation, SSR, and source replacement in a selected bundle. Isolation between multiple active bundles remains untested. The published canary also passes the parent-accept compiler reproduction in CJS and ESM through activation and a later accepted edit.

Keep activation provenance, native runtime updates, and paired Web publication under the existing generation owner. Gates retain original promises through concurrent lazy requests and reject source supersession, failed compilation, and shutdown.

The controller gains lifecycle branches. Ripwire still flags controller complexity and recent generation churn. Keep the shared session binding cohesive rather than extract callbacks solely to reduce the metric. The native and controller regressions cover these paths; no quality acknowledgment or baseline reset was added.
@github-actions

github-actions Bot commented Oct 6, 2026 •

Copy link
Copy Markdown
Contributor

Benchmark results

Case Base Head Delta
build-256-ssr 1620.6 ms 1598.5 ms -1.4%
dev-48-ssr 755.0 ms 755.4 ms +0.1%

@pkg-pr-new

pkg-pr-new Bot commented Oct 6, 2026 •

Copy link
Copy Markdown

Open in StackBlitz

pnpm add https://pkg.pr.new/rsbuild-plugin-react-router@be20e83

commit: be20e83

@codspeed

codspeed Bot commented Oct 6, 2026 •

Copy link
Copy Markdown

Merging this PR will not alter performance

⚠️ 1 benchmark 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

✅ 1 untouched benchmark
⏩ 2 skipped benchmarks1


Comparing codex/ssr-lazy-compilation (be20e83) with main (a09dd6a)

Open in CodSpeed

Footnotes

  1. 2 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports. ↩

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.

1 participant