| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Sorry, something went wrong.
|
Review requested:
|
Sorry, something went wrong.
Codecov Report❌ Patch coverage is 97.95918% with 1 line in your changes missing coverage. Please review.
@@ Coverage Diff @@
## main #65326 +/- ##
=======================================
Coverage 90.13% 90.13%
=======================================
Files 752 752
Lines 251568 251639 +71
Branches 47270 47285 +15
=======================================
+ Hits 226759 226827 +68
- Misses 16168 16174 +6
+ Partials 8641 8638 -3
... and 38 files with indirect coverage changes 🚀 New features to boost your workflow:
|
Sorry, something went wrong.
Sorry, something went wrong.
|
This seems good, but surely there should be some tests that assert the caching behavior, to avoid regressions? |
Sorry, something went wrong.
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>
Commit Queue failed- Loading data for nodejs/node/pull/65326 ✔ Done loading data for nodejs/node/pull/65326 ----------------------------------- PR info ------------------------------------ Title module: cache nearest parent package.json per directory (#65326) Author Shelley Vohr <shelley.vohr@gmail.com> (@codebytere) Branch codebytere:perf/module-parent-package-json-dir-cache -> nodejs:main Labels module, commit-queue Commits 1 - module: cache nearest parent package.json per directory Committers 1 - Shelley Vohr <shelley.vohr@gmail.com> PR-URL: https://github.com/nodejs/node/pull/65326 Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Jordan Harband <ljharb@gmail.com> ------------------------------ Generated metadata ------------------------------ PR-URL: https://github.com/nodejs/node/pull/65326 Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Jordan Harband <ljharb@gmail.com> -------------------------------------------------------------------------------- ℹ This PR was created on Sun, 16 Aug 2026 15:51:12 GMT ✔ Approvals: 3 ✔ - Yagiz Nizipli (@anonrig) (TSC): https://github.com/nodejs/node/pull/65326#pullrequestreview-4947040173 ✔ - James M Snell (@jasnell) (TSC): https://github.com/nodejs/node/pull/65326#pullrequestreview-4948264808 ✔ - Jordan Harband (@ljharb): https://github.com/nodejs/node/pull/65326#pullrequestreview-4953177652 ✔ Last GitHub CI successful ℹ Last Full PR CI on 2026-08-16T18:43:54Z: https://ci.nodejs.org/job/node-test-pull-request/75894/ ⚠ Commits were pushed after the last Full PR CI run: ⚠ - module: cache nearest parent package.json per directory - Querying data for job/node-test-pull-request/75894/ ✔ Build data downloaded - Querying failures of job/node-test-commit/90623/ ✔ Data downloaded ✘ 2 failure(s) on the last Jenkins CI run -------------------------------------------------------------------------------- ✔ Aborted `git node land` session in /home/runner/work/node/node/.ncuhttps://github.com/nodejs/node/actions/runs/32157693157 |
Sorry, something went wrong.
Sorry, something went wrong.
Sorry, something went wrong.
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> PR-URL: #65326 Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Jordan Harband <ljharb@gmail.com>
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> PR-URL: #65326 Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Jordan Harband <ljharb@gmail.com>
| Back | FazBrowse Home | New Git URL |
Cold require() of a 1000-module CommonJS tree gets ~6 % faster (100 runs, ***) and module/module-require.js type='.js' +13.7 %, by looking up the nearest parent package.json once per directory instead of once per file.
getNearestParentPackageJSON(checkPath) - called for every CommonJS module to find "type", and by findPackageJSON - 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-path behavior 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-module and test-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.