Skip to content

Commit 82249f3

Browse files
committed
module: print amount of load time of a cjs module
1 parent 1264414 commit 82249f3

File tree

3 files changed

+69
-4
lines changed

3 files changed

+69
-4
lines changed

lib/internal/modules/cjs/loader.js

+40-4
Original file line numberDiff line numberDiff line change
@@ -359,7 +359,19 @@ function setModuleParent(value) {
359359
moduleParentCache.set(this, value);
360360
}
361361

362-
let debug = require('internal/util/debuglog').debuglog('module', (fn) => {
362+
const { debuglog, isDebugEnabled } = require('internal/util/debuglog');
363+
364+
let debug = debuglog('module', (fn) => {
365+
debug = fn;
366+
});
367+
368+
let hrtimeBigIntTimingFn = () => {
369+
hrtimeBigIntTimingFn = isDebugEnabled('timing_module_cjs') ? process.hrtime.bigint : () => 0
370+
371+
return hrtimeBigIntTimingFn()
372+
};
373+
374+
let debugTiming = debuglog('timing_module_cjs', (fn) => {
363375
debug = fn;
364376
});
365377

@@ -958,6 +970,10 @@ function getExportsForCircularRequire(module) {
958970
return module.exports;
959971
}
960972

973+
function logTiming(request, parent, start) {
974+
debugTiming('[%s] [%s]: %d ms', parent?.id || '', request, Number((hrtimeBigIntTimingFn() - start)) / 1e6);
975+
}
976+
961977
/**
962978
* Load a module from cache if it exists, otherwise create a new module instance.
963979
* 1. If a module already exists in the cache: return its exports object.
@@ -966,10 +982,12 @@ function getExportsForCircularRequire(module) {
966982
* 3. Otherwise, create a new module for the file and save it to the cache.
967983
* Then have it load the file contents before returning its exports object.
968984
* @param {string} request Specifier of module to load via `require`
969-
* @param {string} parent Absolute path of the module importing the child
985+
* @param {Module} parent Absolute path of the module importing the child
970986
* @param {boolean} isMain Whether the module is the main entry point
971987
*/
972988
Module._load = function(request, parent, isMain) {
989+
const start = hrtimeBigIntTimingFn();
990+
973991
let relResolveCacheIdentifier;
974992
if (parent) {
975993
debug('Module._load REQUEST %s parent: %s', request, parent.id);
@@ -984,8 +1002,14 @@ Module._load = function(request, parent, isMain) {
9841002
if (cachedModule !== undefined) {
9851003
updateChildren(parent, cachedModule, true);
9861004
if (!cachedModule.loaded) {
987-
return getExportsForCircularRequire(cachedModule);
1005+
const result = getExportsForCircularRequire(cachedModule);
1006+
1007+
logTiming(request, parent, start);
1008+
1009+
return result;
9881010
}
1011+
1012+
logTiming(request, parent, start);
9891013
return cachedModule.exports;
9901014
}
9911015
delete relativeResolveCache[relResolveCacheIdentifier];
@@ -1001,6 +1025,8 @@ Module._load = function(request, parent, isMain) {
10011025
}
10021026

10031027
const module = loadBuiltinModule(id, request);
1028+
1029+
logTiming(request, parent, start);
10041030
return module.exports;
10051031
}
10061032

@@ -1011,16 +1037,24 @@ Module._load = function(request, parent, isMain) {
10111037
if (!cachedModule.loaded) {
10121038
const parseCachedModule = cjsSourceCache.get(cachedModule);
10131039
if (!parseCachedModule || parseCachedModule.loaded) {
1014-
return getExportsForCircularRequire(cachedModule);
1040+
const result = getExportsForCircularRequire(cachedModule);
1041+
1042+
logTiming(request, parent, start);
1043+
1044+
return result;
10151045
}
10161046
parseCachedModule.loaded = true;
10171047
} else {
1048+
logTiming(request, parent, start);
10181049
return cachedModule.exports;
10191050
}
10201051
}
10211052

10221053
if (BuiltinModule.canBeRequiredWithoutScheme(filename)) {
10231054
const mod = loadBuiltinModule(filename, request);
1055+
1056+
logTiming(request, parent, start);
1057+
10241058
return mod.exports;
10251059
}
10261060

@@ -1068,6 +1102,8 @@ Module._load = function(request, parent, isMain) {
10681102
}
10691103
}
10701104

1105+
logTiming(request, parent, start);
1106+
10711107
return module.exports;
10721108
};
10731109

lib/internal/util/debuglog.js

+5
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,12 @@ function debuglog(set, cb) {
115115
return logger;
116116
}
117117

118+
function isDebugEnabled(set) {
119+
return testEnabled(set);
120+
}
121+
118122
module.exports = {
119123
debuglog,
124+
isDebugEnabled,
120125
initializeDebugEnv,
121126
};
+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { spawnPromisified } from '../common/index.mjs';
2+
import assert from 'node:assert';
3+
import { execPath } from 'node:process';
4+
import { it } from 'node:test';
5+
6+
it('should print the timing information for cjs', async () => {
7+
process.env.NODE_DEBUG = 'timing_module_cjs';
8+
const result = await spawnPromisified(execPath, ['--eval', 'require("url");'], {
9+
env: {
10+
NODE_DEBUG: 'timing_module_cjs',
11+
},
12+
});
13+
14+
assert.strictEqual(result.code, 0);
15+
assert.strictEqual(result.signal, null);
16+
assert.strictEqual(result.stdout, '');
17+
18+
const firstLine = result.stderr.split('\n').find(line => line.includes('[url]'));
19+
20+
assert.notStrictEqual(firstLine, undefined);
21+
assert.ok(firstLine.includes('TIMING_MODULE_CJS'), `Not found TIMING_MODULE_CJS on ${firstLine}`);
22+
assert.ok(firstLine.includes('[url]:'), `Not found [url]: on ${firstLine}`);
23+
assert.ok(firstLine.endsWith('ms'), `Not found ms on ${firstLine}`);
24+
});

0 commit comments

Comments
 (0)