facebook / metro

🚇 The JavaScript bundler for React Native
https://metrobundler.dev
MIT License
5.24k stars 626 forks source link

Resolver perf: Weakly cache normalisation of `exports` field (4/n) #1334

Closed robhogan closed 2 months ago

robhogan commented 2 months ago

Summary: Typically, a given package is required multiple times within a project, but currently we normalise the same exports JSON for every dependency.

In RNTester, only three of its dependencies have non-primitive exports fields:

/node_modules/babel/runtime
/node_modules/react
/packages/react-native-test-library

But these are referenced 760 times, meaning 760 calls to the internal normalizeExportsField.

This diff uses the property of Metro's upstream ModuleCache._packageCache, which avoids reading/parsing package.json unless it has changed. This makes exports stable, and (when it is non-primitive), weakly referenceable.

By caching these values we reduce time spent in normalizeExportsField by ~10x and resolution time overall by 10% for RNTester, though the impact is likely to be larger for larger projects. By using a WeakMap, the cache can be GCed as corresponding packages are deleted from ModuleCache.

- **[Performance]**: Cache normalisation of `exports` fields for improved resolution performance.

Differential Revision: D61841586

facebook-github-bot commented 2 months ago

This pull request was exported from Phabricator. Differential Revision: D61841586

facebook-github-bot commented 2 months ago

This pull request was exported from Phabricator. Differential Revision: D61841586

facebook-github-bot commented 2 months ago

This pull request was exported from Phabricator. Differential Revision: D61841586

facebook-github-bot commented 2 months ago

This pull request has been merged in facebook/metro@16d2205f81bf3ba0aa301bdfb7ae12fd81379f03.