Repository navigation
Commit dbbdcd3
perf(void): reuse unchanged source analysis during dev rescans (#543)
## Issue
Saving a page currently re-reads and analyzes unchanged source files,
then regenerates routing output even when only the page body changed.
This adds unnecessary work as the app grows.
## Fix
This change caches file-derived analysis, invalidates edited files
through the watcher, and skips route-entry regeneration and route-module
invalidation when routing inputs remain unchanged. Recent writes are
conservatively re-analyzed to preserve freshness. Layout inventories are
deterministic, and returned Markdown metadata cannot mutate the cached
analysis. Startup and file changes serialize regeneration so the
generated files and successful-input checkpoint stay consistent. Watcher
failures are logged and retried on a later save. Auth provider/dialect
settings participate in change detection, and missing generated routing
files are repaired on the next source save.
The implementation is shared across React, Vue, Svelte, and Solid Pages.
**The benchmarks below measure React only.**
## Results
Measured from file write to the updated heading appearing in Chrome,
using Cloudflare dev with local workerd on an Apple M5:
| Generated pages | Update | Before | After | Time saved | Change |
|---:|---|---:|---:|---:|---:|
| 1 | Component HMR | 97.0 ms | 96.4 ms | 0.6 ms | −0.7% |
| 1 | Server-page reload | 132.9 ms | 142.9 ms | −10.0 ms | +7.5% |
| 100 | Component HMR | 95.2 ms | 96.8 ms | −1.6 ms | +1.7% |
| 100 | Server-page reload | 119.5 ms | 141.6 ms | −22.2 ms | +18.5% |
| 1,000 | Component HMR | 350.1 ms | 98.6 ms | **251.5 ms** | **−71.8%**
|
| 1,000 | Server-page reload | 329.8 ms | 167.2 ms | **162.6 ms** |
**−49.3%** |
Each fixture includes two additional fixed pages. Results average
session medians across ten paired sessions per size, with 360 timed
saves overall and seeded, sequential variant ordering after warmup.
Both 1,000-page improvements are statistically significant after Holm
correction across six comparisons (`p = 0.0117`). The 95% savings
intervals are **235–268 ms** for HMR and **123–197 ms** for reloads.
Smaller fixtures show no statistically clear improvement or regression.
Validation:
- Regression coverage includes overlapping startup/saves; retry after
write, auth-generation, and invalidation failures; changed auth
settings; deleted outputs; stable layout ordering; and metadata
isolation. Body-only saves return to the fast path after recovery.
- Latest-base verification (`36a3697f`): core build, 465
routing/cache/navigation and email unit/integration tests, and all 33
workspace typecheck tasks passed. The targeted run skipped 13 tests.
- With preceding base `cd480dde`: affected suite passed 10,936 tests;
full suite passed 14,314 tests, with 31 skipped.
- Formatting and lint passed.
- Real Cloudflare dev with Chrome: loader and middleware body edits ran
fresh code without restarting the isolate. A forced generated-file write
failure was logged without terminating the server; the next save
regenerated the POST route and its types. A body-only save also repaired
deleted route types. No browser runtime errors.
- Node production Pages coverage is required. Optional Bun/Deno
availability probes retain the 10-second timeout.
The performance figures above are from the original benchmark run; this
follow-up was verified for correctness.
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: LongYinan <github@lyn.one>1 parent 3d8f848 commit dbbdcd3
8 files changed
Lines changed: 822 additions & 146 deletions
File tree
- packages/void
- src
- pages
- test
- integration
- unit
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | | - | |
| 1 | + | |
2 | 2 | | |
3 | 3 | | |
4 | 4 | | |
| |||
16 | 16 | | |
17 | 17 | | |
18 | 18 | | |
| 19 | + | |
19 | 20 | | |
20 | 21 | | |
21 | 22 | | |
| |||
222 | 223 | | |
223 | 224 | | |
224 | 225 | | |
225 | | - | |
| 226 | + | |
| 227 | + | |
226 | 228 | | |
227 | 229 | | |
228 | 230 | | |
| |||
298 | 300 | | |
299 | 301 | | |
300 | 302 | | |
301 | | - | |
302 | | - | |
| 303 | + | |
| 304 | + | |
| 305 | + | |
| 306 | + | |
| 307 | + | |
303 | 308 | | |
304 | 309 | | |
305 | 310 | | |
| |||
331 | 336 | | |
332 | 337 | | |
333 | 338 | | |
| 339 | + | |
334 | 340 | | |
335 | | - | |
336 | | - | |
337 | | - | |
| 341 | + | |
| 342 | + | |
| 343 | + | |
| 344 | + | |
338 | 345 | | |
339 | | - | |
340 | | - | |
| 346 | + | |
| 347 | + | |
| 348 | + | |
341 | 349 | | |
342 | 350 | | |
343 | 351 | | |
| |||
354 | 362 | | |
355 | 363 | | |
356 | 364 | | |
357 | | - | |
| 365 | + | |
358 | 366 | | |
359 | 367 | | |
360 | 368 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
11 | 11 | | |
12 | 12 | | |
13 | 13 | | |
| 14 | + | |
14 | 15 | | |
15 | 16 | | |
16 | 17 | | |
| |||
168 | 169 | | |
169 | 170 | | |
170 | 171 | | |
171 | | - | |
172 | | - | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
173 | 176 | | |
174 | 177 | | |
175 | 178 | | |
| |||
0 commit comments