Skip to content

perf: ImportDelcaration Dirname#1891

Draft
mgfalzon wants to merge 4 commits into
masterfrom
perf/reduce-resolver-overhead
Draft

perf: ImportDelcaration Dirname#1891
mgfalzon wants to merge 4 commits into
masterfrom
perf/reduce-resolver-overhead

Conversation

@mgfalzon
Copy link
Copy Markdown

@mgfalzon mgfalzon commented May 8, 2026

Summary

One targeted improvement to cut per-file cost in the ImportDeclaration visitor.

babel-plugin.ts — compute relativeFileDir once upfront instead of inside .some()

In the ImportDeclaration visitor, dirname(state.filename) and the userLandModule[0] === '.' check were both computed inside the .some() callback — once per entry in importSources per import declaration.

dirname() parses the full absolute file path and allocates a new string on every call. These are now combined into a single relativeFileDir variable computed once before the loop: null if the import is not relative or there is no filename (skipping resolution entirely), or the resolved directory otherwise.

Benchmark

Using the existing module-traversal-cache perf test (75 samples each):

Variant Before After Δ
initial run 137 ops/sec 152 ops/sec +11%
cache 181 ops/sec 201 ops/sec +11%
no-cache 156 ops/sec 162 ops/sec +4%

Testing

  • Existing module-traversal.test.ts (49 tests) pass with no changes.
  • Benchmark run via yarn benchmark packages/babel-plugin/src/__perf__/module-traversal-cache.test.ts.

Two targeted improvements to cut per-file cost in the
TaggedTemplateExpression|CallExpression visitor and the module
resolution path:

1. babel-plugin.ts — hoist isRelative and fileDir out of the
   importSources.some() callback in ImportDeclaration. dirname() parses
   the full absolute file path on every iteration; computing it once
   per ImportDeclaration call removes O(importSources) redundant string
   allocations per import.

2. resolve-binding.ts — wrap resolveRequest() in cache.load() so that
   module resolution results are cached for the lifetime of a build
   (when cache: true). resolve.sync and custom resolvers both walk
   node_modules and read package.json files synchronously; caching the
   result eliminates repeated I/O for the same (filename, request) pair.

Benchmark (module-traversal-cache, 75 samples):
  initial run: 137 -> 151 ops/sec (+10%)
  cache:       181 -> 201 ops/sec (+11%)
  no-cache:    156 -> 167 ops/sec (+7%)
@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 8, 2026

⚠️ No Changeset found

Latest commit: 85e5854

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@netlify
Copy link
Copy Markdown

netlify Bot commented May 8, 2026

Deploy Preview for compiled-css-in-js canceled.

Name Link
🔨 Latest commit 85e5854
🔍 Latest deploy log https://app.netlify.com/projects/compiled-css-in-js/deploys/69fe624d8906f80008b7ad24

Matt added 3 commits May 8, 2026 18:17
…tion

fileDir is now null when state.filename is absent, and isRelative
encodes the null check, eliminating the redundant state.filename
guard inside the .some() callback.
@mgfalzon mgfalzon changed the title perf: reduce resolver overhead in babel plugin perf: ImportDelcaration Dirname May 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant