perf: release inner-graph state, fast-path inlined-export checks and skip inlined entry re-parse#21167
Conversation
…export checks - Release per-module InnerGraph state once inferDependencyUsage has fired its callbacks; the state (two Maps plus Sets of closures capturing AST nodes per module) was retained for the whole compilation lifetime. - Add ExportsInfo.hasInlinedUsedName as an allocation-free check used by isExportInlined on the connection-condition hot path, with a per- ExportsInfo flag so modules without inlined exports answer with a single property read. - Keep HarmonyImportSpecifierDependency connections unconditional when usedByExports is true, no branch guards exist and inlineExports is disabled, restoring the fast path for development and cached builds. https://claude.ai/code/session_01Ab1MSNJvUMuuesmS81226v
…eded avoidEntryIife re-parsed and scope-analyzed every chunk module during renderMain, including the inlined entry, which for a concatenated entry is the whole application source. Codegen already reports the rendered entry's top-level declarations, so for a single inlined entry the collision check runs against that set and the parse only happens when a collision actually requires renaming. https://claude.ai/code/session_01Ab1MSNJvUMuuesmS81226v
- ExportsInfo._updateHash tracks the visited path with add/delete on a shared set instead of copying it on every level. - getPathInAst binary-searches ordered sibling ranges instead of a linear scan per lookup. - getUsedNamesInScopeInfo uses nested maps instead of building a string key per lookup. https://claude.ai/code/session_01Ab1MSNJvUMuuesmS81226v
🦋 Changeset detectedLatest commit: 187d2fd The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
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 |
|
This PR is packaged and the instant preview is available (309ff77). Install it locally:
npm i -D webpack@https://pkg.pr.new/webpack@309ff77
yarn add -D webpack@https://pkg.pr.new/webpack@309ff77
pnpm add -D webpack@https://pkg.pr.new/webpack@309ff77 |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #21167 +/- ##
=======================================
Coverage 92.58% 92.59%
=======================================
Files 587 587
Lines 63666 63750 +84
Branches 17636 17664 +28
=======================================
+ Hits 58946 59027 +81
- Misses 4720 4723 +3
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Merging this PR will degrade performance by 57.08%
|
| Mode | Benchmark | BASE |
HEAD |
Efficiency | |
|---|---|---|---|---|---|
| ❌ | Memory | benchmark "lodash", scenario '{"name":"mode-development-rebuild","mode":"development","watch":true}' |
130 KB | 858.8 KB | -84.86% |
| ❌ | Memory | benchmark "many-modules-esm", scenario '{"name":"mode-production","mode":"production"}' |
7.8 MB | 11.4 MB | -31.37% |
| ❌ | Memory | benchmark "many-modules-commonjs", scenario '{"name":"mode-production","mode":"production"}' |
7.4 MB | 9.7 MB | -23.88% |
Tip
Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.
Comparing perf/inner-graph-release-and-concat-fast-paths (187d2fd) with main (6e52971)
|
Regarding the two CodSpeed memory regressions: I verified Generated by Claude Code |
|
Follow-up on the updated CodSpeed report (now claiming 3 memory regressions): I re-verified all three locally against the exact base (6e52971) using a sampling heap profiler measuring total allocations (CodSpeed's Memory mode metric), 3 interleaved runs per side:
Retained heap and peak RSS were also checked earlier with the same result. I believe all three flags are measurement instability and can be acknowledged on CodSpeed. Generated by Claude Code |
Summary
Profiling a 7k-module three.js production build against v5.107.2 showed regressed memory (+34 MB retained heap) and large per-build costs: inner-graph state was retained for the whole compilation, every harmony import connection became conditional with an allocating inline-export check, and
avoidEntryIifere-parsed the entire rendered entry (the whole concatenated app) on every build. This PR releases the inner-graph state after inference, adds allocation-free fast paths for the inlined-export checks, skips the entry re-parse when codegen-reported top-level declarations show no collision, and trims allocations in export hashing and concatenation lookups. On the benchmark: initial build ~14.0s → ~8.8s, watch rebuild ~8.9s → ~3.4s, retained heap 347 MB → 303 MB, with byte-identical output.What kind of change does this PR introduce?
perf
Did you add tests for your changes?
No new tests; behavior is unchanged and covered by the existing suites (ConfigTestCases, StatsTestCases, TestCasesProduction/Development, inline-exports, inner-graph, side-effects all pass).
Does this PR introduce a breaking change?
No.
If relevant, what needs to be documented once your changes are merged or what have you already documented?
n/a
Use of AI
This PR was developed with Claude Code (AI agent): it profiled the builds, located the regressions, wrote the patches and benchmarks, and ran the test suites; the work was directed and reviewed by the requester.
Generated by Claude Code