module: cache nearest parent package.json per directory - #65326
Open
codebytere wants to merge 1 commit into
Open
module: cache nearest parent package.json per directory#65326codebytere wants to merge 1 commit into
codebytere wants to merge 1 commit into
Conversation
getNearestParentPackageJSON() memoized its answer per file, so every module loaded still made one native call, and TraverseParent() builds several std::filesystem::path temporaries per directory level and serializes the whole package.json, which the JS side then usually discarded because it already had that package.json deserialized. The native traversal starts at the directory of the given path, so the answer only depends on that directory: key the memo by it (following NormalizePath()'s trailing-separator rule), so that all modules in a directory share one native call. When the permission model is enabled the traversal also depends on the read permissions in effect at call time, so that configuration keeps the per-file cache. Loading a 1000-module tree spread over ~240 directories goes from 1000 to 236 native calls. Signed-off-by: Shelley Vohr <shelley.vohr@gmail.com>
Collaborator
|
Review requested:
|
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #65326 +/- ##
=======================================
Coverage 90.13% 90.14%
=======================================
Files 752 752
Lines 251568 251599 +31
Branches 47270 47289 +19
=======================================
+ Hits 226759 226799 +40
+ Misses 16168 16146 -22
- Partials 8641 8654 +13
🚀 New features to boost your workflow:
|
anonrig
approved these changes
Aug 16, 2026
Collaborator
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Cold
require()of a 1000-module CommonJS tree gets ~6 % faster (100 runs, ***) andmodule/module-require.js type='.js'+13.7 %, by looking up the nearest parent
package.jsononce per directory instead of once per file.getNearestParentPackageJSON(checkPath)- called for every CommonJS module to find"type", and byfindPackageJSON-memoized per file, so N modules in a directory meant N calls into the native package.json reader. The result only depends
on the directory the traversal starts from, so the JS-side cache is now keyed by that directory, derived with the same rule
the native side uses (trailing separator → that directory, else
dirname). With the permission model enabled the per-pathbehavior is kept, because the native call performs a per-path read check. Same return values, same objects, same lifetime
(both caches were already permanent). 1000 native calls → 236 for the tree above.
Tests: behavior is unchanged;
test-module-*,test-require-*,test-esm-*,es-moduleandtest-permission-*(which exercises the per-path branch) pass. Happy to add a call-count test if wanted.
Disclosure: the code, test, measurements and this description were written by Claude Code, directed and reviewed by @codebytere.