module: add extra caching layer
This adds an extra modules caching layer that operates on the parent's `path` property and the current require argument. That together can be used as unique identifier to speed up loading the same module more than once. It is a cache on top of the current modules cache. It has the nice feature that this cache does not only work in the same file but it works for the whole current directory. So if the same file is loaded in any other file from the same directory, it will also hit this cache instead of having to resolve the file again. To keep it backwards compatible with the old modules cache, it detects invalidation of that cache. PR-URL: https://github.com/nodejs/node/pull/26970 Refs: https://github.com/nodejs/node/pull/25362 Reviewed-By: Guy Bedford <guybedford@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
This commit is contained in:
parent
d0043136e5
commit
0f190a5bed
@ -79,6 +79,8 @@ const {
|
||||
|
||||
const isWindows = process.platform === 'win32';
|
||||
|
||||
const relativeResolveCache = Object.create(null);
|
||||
|
||||
let requireDepth = 0;
|
||||
let statCache = null;
|
||||
function stat(filename) {
|
||||
@ -568,14 +570,28 @@ Module._resolveLookupPaths = function(request, parent, newReturn) {
|
||||
// Then have it load the file contents before returning its exports
|
||||
// object.
|
||||
Module._load = function(request, parent, isMain) {
|
||||
let relResolveCacheIdentifier;
|
||||
if (parent) {
|
||||
debug('Module._load REQUEST %s parent: %s', request, parent.id);
|
||||
// Fast path for (lazy loaded) modules in the same directory. The indirect
|
||||
// caching is required to allow cache invalidation without changing the old
|
||||
// cache key names.
|
||||
relResolveCacheIdentifier = `${parent.path}\x00${request}`;
|
||||
const filename = relativeResolveCache[relResolveCacheIdentifier];
|
||||
if (filename !== undefined) {
|
||||
const cachedModule = Module._cache[filename];
|
||||
if (cachedModule !== undefined) {
|
||||
updateChildren(parent, cachedModule, true);
|
||||
return cachedModule.exports;
|
||||
}
|
||||
delete relativeResolveCache[relResolveCacheIdentifier];
|
||||
}
|
||||
}
|
||||
|
||||
const filename = Module._resolveFilename(request, parent, isMain);
|
||||
|
||||
const cachedModule = Module._cache[filename];
|
||||
if (cachedModule) {
|
||||
if (cachedModule !== undefined) {
|
||||
updateChildren(parent, cachedModule, true);
|
||||
return cachedModule.exports;
|
||||
}
|
||||
@ -595,6 +611,9 @@ Module._load = function(request, parent, isMain) {
|
||||
}
|
||||
|
||||
Module._cache[filename] = module;
|
||||
if (parent !== undefined) {
|
||||
relativeResolveCache[relResolveCacheIdentifier] = filename;
|
||||
}
|
||||
|
||||
let threw = true;
|
||||
try {
|
||||
@ -603,6 +622,9 @@ Module._load = function(request, parent, isMain) {
|
||||
} finally {
|
||||
if (threw) {
|
||||
delete Module._cache[filename];
|
||||
if (parent !== undefined) {
|
||||
delete relativeResolveCache[relResolveCacheIdentifier];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user