perf: skip empty-query concat, bound star scan, flatten alias predicate#574
perf: skip empty-query concat, bound star scan, flatten alias predicate#574alexander-akait merged 4 commits intomainfrom
Conversation
|
🦋 Changeset detectedLatest commit: b48a08b 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 |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #574 +/- ##
==========================================
+ Coverage 96.54% 96.66% +0.11%
==========================================
Files 50 50
Lines 2927 2939 +12
Branches 922 931 +9
==========================================
+ Hits 2826 2841 +15
+ Misses 85 82 -3
Partials 16 16
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Merging this PR will improve performance by ×2.1
|
| Mode | Benchmark | BASE |
HEAD |
Efficiency | |
|---|---|---|---|---|---|
| ⚡ | Memory | array-alias: @ -> [preferred, fallback] (warm) |
1.8 KB | 1.5 KB | +16.92% |
| ⚡ | Memory | pathological-deep-stack: alias chain of 50 (warm) |
16.7 KB | 14.7 KB | +13.75% |
| ⚡ | Simulation | cache-predicate: mixed cached/uncached requests (warm) |
4 ms | 1.9 ms | ×2.1 |
Comparing claude/simplify-and-optimize-NgYnr (b48a08b) with main (f28d8b9)
7bc61d9 to
0553a3e
Compare
* `ImportsFieldPlugin`: skip `request + query + fragment` when both
`query` and `fragment` are empty (the common case), matching
`ExportsFieldPlugin`.
* `util/entrypoints`: replace per-key `lastIndexOf("*")` (which scans
the full string) with a bounded `includes("*", patternIndex + 1)` so
single-star keys finish in one pass.
* `AliasUtils`: factor the duplicated `absolutePath !== null &&
startsWith(absolutePath)` clause out of both ternary branches and
destructure `absolutePath` once per option.
https://claude.ai/code/session_015jvA8SSpQbK7E2FeCEECdr
* `util/entrypoints.findMatch`: remove the unreachable `perRequest.has(request)` follow-up. `computeFindMatch` returns `MatchTuple | null` (never `undefined`), and `Map.get` on a `set(k, null)` returns `null`, not `undefined` — so the prior `cached !== undefined` branch already handles cached-null. The `has` line was dead code, adding a wasted lookup on every miss. * `AliasFieldPlugin`: store the `NO_FIELD_OBJECT` sentinel from the cache-miss path and let the existing `=== NO_FIELD_OBJECT` block emit the warning, deduplicating the two identical "log + return callback" branches. https://claude.ai/code/session_015jvA8SSpQbK7E2FeCEECdr
* `DirectoryExistsPlugin` / `FileExistsPlugin`: fold the two near-identical miss branches (stat error / wrong type) into a single `if (err || !stat || !stat.isDirectory()/.isFile())` block. The `missingDependencies.add` and the log call now live in one place; the message picks the right wording via a ternary. * `TsconfigPathsPlugin._selectPathsDataForContext` (per resolve): reorder the longest-prefix predicate so the cheap `context.length > longestMatchLength` integer compare gates the `isSubPath()` `startsWith` scan. Every shorter candidate skips the scan outright. * `TsconfigPathsPlugin.tsconfigPathsToResolveOptions` (config load): hoist the `[/\\]\*$` wildcard-tail regex to a module-level const, and replace the `absolutePaths.map(...) .filter(Boolean)` spread chain with a direct loop — dropping two throwaway arrays plus the spread iterator per `*` mapping. https://claude.ai/code/session_015jvA8SSpQbK7E2FeCEECdr
…elect * `Resolver.parse`: compute `getType(part.request)` once and reuse it for both `module` and `internal`. The two-call form is kept only for the `\0#`-escape case (where `parseIdentifier` produces a fresh `part.request` whose prefix differs from `identifier`'s), detected via a pointer-equality check that the no-query / no-fragment fast path satisfies for the common case. Inline `isDirectory` to drop a method dispatch. * `DescriptionFileUtils.loadDescriptionFile`: hoist the per-filename iterator and the per-level done callback out of `findDescriptionFile`. Both close over the mutable `directory` and now allocate once per call instead of once per directory level walked. Multiple `DescriptionFilePlugin` taps fire per resolve and each climbs several dirs, so a 5-deep walk drops from ~10 closures to ~2. * `TsconfigPathsPlugin._selectPathsDataForContext` (per resolve): defer the `allContexts[context]` property access until we know the context actually matches. Non-matching candidates skip the lookup entirely; combined with the prior length-then-`isSubPath` reorder, every shorter context is now rejected with one integer compare. https://claude.ai/code/session_015jvA8SSpQbK7E2FeCEECdr
0d1d505 to
b48a08b
Compare
ImportsFieldPlugin: skiprequest + query + fragmentwhen bothqueryandfragmentare empty (the common case), matchingExportsFieldPlugin.util/entrypoints: replace per-keylastIndexOf("*")(which scansthe full string) with a bounded
includes("*", patternIndex + 1)sosingle-star keys finish in one pass.
AliasUtils: factor the duplicatedabsolutePath !== null && startsWith(absolutePath)clause out of both ternary branches anddestructure
absolutePathonce per option.https://claude.ai/code/session_015jvA8SSpQbK7E2FeCEECdr