Skip to content

optimize alias plugin for huge alias objects#438

Draft
VincentBailly wants to merge 5 commits intowebpack:mainfrom
VincentBailly:optimize-alias-plugin
Draft

optimize alias plugin for huge alias objects#438
VincentBailly wants to merge 5 commits intowebpack:mainfrom
VincentBailly:optimize-alias-plugin

Conversation

@VincentBailly
Copy link
Copy Markdown

The alias plugin gets very slow when the webpack config has many aliases.

This PR aims to re-implement the features of the current alias plugin but in a more efficient manner:

  • Create only the minimum amount of closure objects as possible
  • Memoize string operations by running them in the constructor of the plugin

@linux-foundation-easycla
Copy link
Copy Markdown

linux-foundation-easycla bot commented Dec 10, 2024

CLA Not Signed

Comment thread lib/AliasPlugin.js
this.source = source;
this.options = Array.isArray(options) ? options : [options];
for (const item of this.options) {
item.nameWithSlash = item.name + "/";
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why we need it?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's just a memoization so we don't do this concatenation on every resolution, the concatenation creates an object that is short lived, creating work for the garbage collector. By creating the concatenated string once, storing it and reusing it we save the memory overhead of creating many times the same temporary objects.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the aliasing object gets truly large, it'd be worth investing in adding a dependency on a prefix-tree implementation that can handle the optional * component in the path, and use that to optimize the matching logic.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To avoid shape changes it would be best to have this.options consist of fresh objects that have all required properties.

@alexander-akait
Copy link
Copy Markdown
Member

Tests are failed

alexander-akait pushed a commit that referenced this pull request Apr 16, 2026
Hoists per-option strings (nameWithSlash, absolutePath, wildcardPrefix/Suffix)
out of the hot AliasPlugin scan into AliasUtils#compileAliasOptions, invoked
once per resolver in AliasPlugin#apply (and in TsconfigPathsPlugin when a
paths map is built). The per-resolve loop then runs with no string concat,
no name.split("*"), and no resolver.join per unmatched entry - the cost that
dominated projects with hundreds of webpack aliases (see #438).

Adds two benchmark cases covering the monorepo-scale scenario:
- huge-alias-list: 300 non-matching + 8 matching aliases, match near end
- huge-alias-miss: 300 aliases + requests that never match any

Local wall-clock numbers (Node 22, tinybench):
                            before    after    delta
  huge-alias-list           225 ops   405 ops  +80%
  huge-alias-miss           453 ops   893 ops  +97%
  large-alias-list          653 ops   856 ops  +31%

https://claude.ai/code/session_01ERSdt7j3dKwd9MxNbuuXnm
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants