Repository navigation
perf(start-plugin-core): reuse the Rsbuild dev client build when a rebuild cannot change it - #8800
mattcosta7 wants to merge 5 commits into
Conversation
…build cannot change it Reuse the previous normalized client build and dev manifest when the compilation directly follows the captured one, no file was removed, the chunk graph fingerprint is unchanged, and the active static imports of rebuilt modules and their importers are unchanged. The fingerprint covers only the files normalization reads, so HMR update files and other assets do not defeat reuse, and it is independent of chunk iteration order, which HMR rebuilds shuffle. Import signatures are recorded once and then updated for rebuilt modules only.
🦋 Changeset detectedLatest commit: ac1e563 The changes in this PR will be included in the next version bump. This PR includes changesets to release 5 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
No actionable comments were generated in the recent review.
|
| Layer / File(s) | Summary |
|---|---|
Rebuild eligibility and snapshot reuse packages/start-plugin-core/src/rsbuild/rebuilt-modules.ts, packages/start-plugin-core/src/rsbuild/normalized-client-build.ts |
New helpers identify rebuilt modules and detect possible import re-resolution. Development capture tracks module-edge signatures and a chunk-graph fingerprint, then reuses the prior normalized build only when its snapshot remains eligible. |
Development manifest update packages/start-plugin-core/src/rsbuild/virtual-modules.ts |
Development manifest updates return early when both the client build and route manifest match their stored references. Otherwise, the code records the route manifest and refreshes the development manifest. |
Reuse tests and benchmarks packages/start-plugin-core/tests/rsbuild/normalized-client-build.test.ts, packages/start-plugin-core/tests/rsbuild/rebuilt-modules.test.ts, packages/start-plugin-core/tests/rsbuild/dev-client-build-reuse.bench.ts, .changeset/rsbuild-dev-client-build-reuse.md |
Tests cover rebuild eligibility and reuse across several types of edits. The benchmark measures normalization and manifest generation before and after a code-only rebuild. A patch changeset records the update. |
Priority:
Estimated code review effort: 3 (Moderate) | ~25 minutes
Change: Refactor
Sequence Diagram(s)
sequenceDiagram
participant RspackCompiler
participant registerClientBuildCapture
participant mayHaveReResolvedImports
participant getRebuiltModulesAndImporters
participant NormalizedClientBuild
participant DevelopmentManifest
RspackCompiler->>registerClientBuildCapture: Advance or invalidate the prior snapshot
registerClientBuildCapture->>mayHaveReResolvedImports: Check changed and removed files
registerClientBuildCapture->>getRebuiltModulesAndImporters: Collect rebuilt modules and importers
registerClientBuildCapture->>NormalizedClientBuild: Reuse eligible snapshot or normalize compilation
NormalizedClientBuild->>DevelopmentManifest: Provide captured client build
DevelopmentManifest->>DevelopmentManifest: Skip update if build and route manifest references match
Possibly related PRs
- TanStack/router#8801: Uses the same rebuilt-module and import re-resolution helpers for incremental import-protection scans.
Suggested labels: package: start-plugin-core
Suggested reviewers: ladybluenotes, schiller-manuel
Merge Risk: 
Minimal · up to ac1e5
-
This change speeds up Rsbuild dev rebuilds by reusing the normalized client build when a rebuild cannot change it. The checks that guard reuse are conservative and tested against real watch builds. No actionable merge-blocking risk was found.
Pre-merge checks: 
4 · 
1
-
Failed checks: 1 warning Passed checks: 4 passed-
Full details: Description check
-
Explanation
The description includes the required Changes, Checklist, and Release Impact sections. It explains the implementation, motivation, benchmarks, tests, changeset, and AI assistance. The checklist item confirming full understanding of the code remains unchecked, but the description is otherwise substantially complete.
-
Full details: Docstring Coverage
-
Explanation
Docstring coverage is 70.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 10 functions across 6 files. (1 skipped: 1 unsupported.)
Resolution
Write docstrings for the functions missing them to satisfy the coverage threshold.
-
Finishing Touches
-
🧪 Generate unit tests (beta)
-
- Create a new PR
-
- Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.
Comment @coderabbitai help to get the list of available commands.
…signatures A rebuilt module could point a dynamic import at a module already in the graph while the chunk kept its name and module count, so the previous manifest was reused with the old route or hydration metadata.
Module identifiers include full loader chains, so keeping the joined identifiers retained about 7.9 KB per first-party module for the life of the dev server. Keys and signatures are now SHA-1 digests.
…r resolution changes A changed package.json import map, exports map or tsconfig paths can re-resolve imports without rebuilding any module, so the edge check saw nothing change. Reuse now also requires that every changed file is a rebuilt module and none is a package.json or tsconfig file.
…ing Rsbuild re-resolution
🎯 Changes
In
rsbuild dev, every rebuild normalizes the client compilation and rebuilds the Start manifest, even for a code-only edit that cannot change either. This reuses the previous result when all of these hold:The fingerprint only includes files normalization reads, so
*.hot-update.*files and other assets don't defeat it. Its lines are sorted because HMR rebuilds reorder chunks between compilations without changing them. Import signatures are recorded once per dev server and then updated for rebuilt modules only. When the client build and route tree are unchanged, the dev manifest isn't rebuilt either.128-route dev rebuild (
tests/rsbuild/dev-client-build-reuse.bench.ts):A rebuild that does change imports or chunks pays the before cost plus the ~1.8 ms check.
Tests: a real Rspack watch test, run with and without
HotModuleReplacementPlugin, compares every captured build with a fresh normalization after code-only, shared-module, CSS, hydration-query and dynamic-import edits, and checks which ones were reused. Weakening the import check or ignoring import changes makes it fail; so did the hot-update and chunk-order problems before they were fixed.rebuilt-modules.tsis also added by #8801; both copies are identical. Rebases cleanly with #8780. If #8588 lands first, its rebase needs to keepgetChunkJsFilesandgetChunkCssFilescallable, since the fingerprint here uses them.Written with an AI coding assistant.
✅ Checklist
🚀 Release Impact
Summary by CodeRabbit