Skip to content

Commit 4b3cc3c

Browse files
zeusdeuxrichardlau
authored andcommitted
loader: speed up line length calc used by moduleProvider
When using a loader, for say TypeScript, the esm loader invokes the `lineLengths` function via `maybeCacheSourceMap` when sourcemaps are enabled. Therefore, `lineLengths` ends up getting called quite often when running large servers written in TypeScript for example. Making `lineLengths` faster should therefore speed up server startup times for anyone using a loader with node with sourcemaps enabled. The change itself is fairly simple and is all about removing creation of unnecessary memory and iterating the whole source content only once with the hope of making the function cache friendly. PR-URL: #50969 Reviewed-By: Yagiz Nizipli <[email protected]> Reviewed-By: Geoffrey Booth <[email protected]> Reviewed-By: Antoine du Hamel <[email protected]> Reviewed-By: Vinícius Lourenço Claro Cardoso <[email protected]> Reviewed-By: Jacob Smith <[email protected]>
1 parent 1e923f1 commit 4b3cc3c

File tree

1 file changed

+20
-8
lines changed

1 file changed

+20
-8
lines changed

lib/internal/source_map/source_map_cache.js

+20-8
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
'use strict';
22

33
const {
4-
ArrayPrototypeMap,
4+
ArrayPrototypePush,
55
JSONParse,
66
ObjectKeys,
77
RegExpPrototypeExec,
8-
RegExpPrototypeSymbolSplit,
98
SafeMap,
9+
StringPrototypeCodePointAt,
1010
StringPrototypeSplit,
1111
} = primordials;
1212

@@ -205,14 +205,26 @@ function dataFromUrl(sourceURL, sourceMappingURL) {
205205
// from. This allows translation from byte offset V8 coverage reports,
206206
// to line/column offset Source Map V3.
207207
function lineLengths(content) {
208-
// We purposefully keep \r as part of the line-length calculation, in
209-
// cases where there is a \r\n separator, so that this can be taken into
210-
// account in coverage calculations.
211-
return ArrayPrototypeMap(RegExpPrototypeSymbolSplit(/\n|\u2028|\u2029/, content), (line) => {
212-
return line.length;
213-
});
208+
const contentLength = content.length;
209+
const output = [];
210+
let lineLength = 0;
211+
for (let i = 0; i < contentLength; i++, lineLength++) {
212+
const codePoint = StringPrototypeCodePointAt(content, i);
213+
214+
// We purposefully keep \r as part of the line-length calculation, in
215+
// cases where there is a \r\n separator, so that this can be taken into
216+
// account in coverage calculations.
217+
// codepoints for \n (new line), \u2028 (line separator) and \u2029 (paragraph separator)
218+
if (codePoint === 10 || codePoint === 0x2028 || codePoint === 0x2029) {
219+
ArrayPrototypePush(output, lineLength);
220+
lineLength = -1; // To not count the matched codePoint such as \n character
221+
}
222+
}
223+
ArrayPrototypePush(output, lineLength);
224+
return output;
214225
}
215226

227+
216228
function sourceMapFromFile(mapURL) {
217229
try {
218230
const fs = require('fs');

0 commit comments

Comments
 (0)