perf(pages): reuse dev stylesheet dependency analysis - #2550
Conversation
commit: |
|
Performance benchmarksCompared 1 improved · 0 regressed · 5 within ±1.5%
View detailed results and traces 🟢 improvement · 🔴 regression · ⚫ change below 1.5% · paired base/head |
|
/bigbonk review for issues |
There was a problem hiding this comment.
Review: perf(pages): reuse dev stylesheet dependency analysis
Reviewed the diff, traced the graph-traversal semantics, ran the targeted tests, and ran vp check (fmt + lint + types all green). No blocking correctness issues — the caching refactor preserves per-entry CSS order and dedup. A few minor/observational notes below.
Verified safe
- Dedup key change (
seenModulesnow keyed by rawmodulePathinstead of the query-strippedcleanModulePath): I traced diamond/shared-import cases. CSS correctness holds becauseseenAssets(per-entry) dedups by asset value and preserves first-encounter order; a query-distinct script id only causes a redundant re-traversal of the same file, never a duplicated or reordered stylesheet. The PR body flags "query-distinct cache identities" as intentional, which matches. - Cache layering: the shared
getModuleDependenciescache is graph-level whilestylesheetAssets/seenAssetsstay per-entry — per-entry order/dedup is correctly recomputed on each traversal. Good separation. - No rejected-promise caching:
collectModuleDependenciescatches parse errors and returns[](never throws), so the generic promise cache never memoizes a rejection. - Escaped
requireprescan: correct.requireis an identifier (unicode-escapable), whereasimportis a keyword (cannot be escaped), so only handling escapes on therequireside is the right asymmetry.isIdentifierNamed(callee, "require")matches on the parser-decoded name, sorequ\u0069re(...)is correctly transformed.
Minor / non-blocking
-
DYNAMIC_REQUEST_PRESCANadds aniflag over the composedDYNAMIC_IMPORT_PRESCAN(ignore-dynamic-requests.ts:29-32).DYNAMIC_IMPORT_PRESCANis/\bimport\s*[(/]/(no flag), but the combined filter is case-insensitive, so thecodefilter will pass e.g.IMPORT (x)while the in-handler gatemayContainDynamicImport(noi) rejects it. Harmless — the filter is a superset and the handler gate is authoritative — but it means the two gates aren't strictly identical. Worth a one-line comment noting the filter is deliberately a superset of the handler gate. -
Test coverage gap for the real dev-Pages path.
tests/pages-router.test.ts"dev Pages dependency metadata reuses exact module ids" only exercisescreateModuleDependencyCachewith a mockcollect; it doesn't touchcreateDevPagesModuleDependencyReader/collectDevPagesAppStylesheetAssets. It's effectively a duplicate unit test of the generic cache under a name that implies integration coverage. The existing_app stylesheet metadata updates when transitive imports changetest does cover the real traversal, so this isn't a coverage hole per se — but consider renaming this new test (e.g. "module dependency cache dedups by exact id") so the intent is clear, or extending it to assert shared reuse across two page entries through the real reader. -
Over-inclusive
REQUIRE_PRESCANon non-word-boundary matches (e.g.myrequireFn,prerequirematch via the un-escaped-letter branch since that branch has no\b). This is strictly narrower than the previouscode.includes("require")and only causes redundant parses (AST check is authoritative), so it's not a regression — just noting it's not a true word-boundary gate for the escaped branch.
Nothing here blocks merge. The perf win is real and the refactor is clean.
|
Review posted to PR #2550. SummaryI reviewed PR #2550 ( Key findings I verified as safe:
Three minor/non-blocking notes posted:
|
d3964a0 to
e51b4a8
Compare
Summary
_appand all page entry traversals while preserving per-entry CSS order and deduplicationrequireidentifiers without admitting unrelated Unicode escapesPerformance
Measured with an excluded local Pages Router fixture containing 485 routes and a heavily shared import graph. Each round cleared the fixture's Vite caches and waited for a rendered route marker.
After the latest review fixes, six alternating cold rounds at the exact PR base and head:
Mean cold readiness improved by 75.3%.
Validation
vp test run tests/pages-router.test.ts -t 'dev Pages (client assets expose|cached ISR HTML keeps|custom error HTML includes|_app stylesheet links use|_app stylesheet metadata|client assets do not treat|dependency metadata reuses exact module ids)'vp test run tests/dynamic-requests-build.test.tsvp run vinext#build