Skip to content

perf(interopDefault): add caching to reduce Proxy overhead by ~2x#421

Merged
pi0 merged 4 commits into
unjs:mainfrom
mcollina:fix/interop-default-perf
Feb 27, 2026
Merged

perf(interopDefault): add caching to reduce Proxy overhead by ~2x#421
pi0 merged 4 commits into
unjs:mainfrom
mcollina:fix/interop-default-perf

Conversation

@mcollina

Copy link
Copy Markdown
Contributor

Summary

  • Add Map-based caching to interopDefault Proxy to reduce repeated lookups
  • Add performance warning to README.md documentation
  • Add benchmark script (test/bench-interop.mjs)

Problem

The interopDefault Proxy wrapper was causing significant performance overhead (60-70x slower than native) due to:

  • Reflect.has() called on every property access
  • Reflect.get() called on every property access
  • .bind() called on every access for functions from default export

Solution

Added a Map-based cache that stores property values after first access, eliminating repeated lookups.

Results:

Scenario Before After Improvement
Named exports 66x slower 39x slower ~2x faster
Fallback to default 38x slower 24x slower ~1.6x faster

The remaining overhead is inherent to JavaScript Proxies and cannot be eliminated while maintaining the same behavior.

Test plan

  • All vitest tests pass
  • Node.js register tests pass
  • Type checking passes
  • Linting passes
  • Benchmark shows ~2x improvement

Closes #420

The interopDefault Proxy wrapper was causing significant performance
overhead (60-70x slower than native) due to:
- Reflect.has() called on every property access
- Reflect.get() called on every property access
- .bind() called on every access for functions from default export

This adds a Map-based cache that stores property values after first
access, eliminating repeated lookups. Results:
- Named exports: 66x -> 39x slower (~2x improvement)
- Fallback to default: 38x -> 24x slower (~1.6x improvement)

The remaining overhead is inherent to JavaScript Proxies and cannot
be eliminated while maintaining the same behavior.

Also adds a warning to README.md about the performance cost of
interopDefault and recommends disabling it for hot paths.

Closes unjs#420
@mcollina mcollina force-pushed the fix/interop-default-perf branch from fe51f12 to 7c3a328 Compare January 28, 2026 15:25

@pi0 pi0 left a comment

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.

Thanks ❤️

@pi0 pi0 merged commit a467d31 into unjs:main Feb 27, 2026
7 checks passed
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.

Performance Issue: interopDefault Proxy adds 60x overhead on property access

2 participants