Skip to content

Commit d348cc5

Browse files
committed
url: faster encodePathChars function
This is roughly twice as fast as before. Signed-off-by: Ruben Bridgewater <[email protected]>
1 parent d96a2ea commit d348cc5

File tree

1 file changed

+31
-19
lines changed

1 file changed

+31
-19
lines changed

lib/internal/url.js

+31-19
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,9 @@ const {
1919
ReflectApply,
2020
ReflectGetOwnPropertyDescriptor,
2121
ReflectOwnKeys,
22+
RegExp,
2223
String,
2324
StringPrototypeCharCodeAt,
24-
StringPrototypeIncludes,
25-
StringPrototypeReplace,
2625
StringPrototypeSlice,
2726
StringPrototypeSplit,
2827
StringPrototypeStartsWith,
@@ -1500,25 +1499,38 @@ function fileURLToPath(path) {
15001499
// - CR: The carriage return character is also stripped out by the `pathname`
15011500
// setter.
15021501
// - TAB: The tab character is also stripped out by the `pathname` setter.
1503-
const percentRegEx = /%/g;
1504-
const backslashRegEx = /\\/g;
1505-
const newlineRegEx = /\n/g;
1506-
const carriageReturnRegEx = /\r/g;
1507-
const tabRegEx = /\t/g;
1502+
const escapePathRegExp = new RegExp(`%|\\n|\\r|\\t${isWindows ? '' : '|\\\\'}`);
1503+
const escapedPathChars = {
1504+
'%': '%25',
1505+
'\n': '%0A',
1506+
'\r': '%0D',
1507+
'\t': '%09',
1508+
'\\': '%5C',
1509+
};
15081510

1511+
// As of V8 10.2 the hand written replacer is faster than using replace with a
1512+
// replacer function.
15091513
function encodePathChars(filepath) {
1510-
if (StringPrototypeIncludes(filepath, '%'))
1511-
filepath = StringPrototypeReplace(filepath, percentRegEx, '%25');
1512-
// In posix, backslash is a valid character in paths:
1513-
if (!isWindows && StringPrototypeIncludes(filepath, '\\'))
1514-
filepath = StringPrototypeReplace(filepath, backslashRegEx, '%5C');
1515-
if (StringPrototypeIncludes(filepath, '\n'))
1516-
filepath = StringPrototypeReplace(filepath, newlineRegEx, '%0A');
1517-
if (StringPrototypeIncludes(filepath, '\r'))
1518-
filepath = StringPrototypeReplace(filepath, carriageReturnRegEx, '%0D');
1519-
if (StringPrototypeIncludes(filepath, '\t'))
1520-
filepath = StringPrototypeReplace(filepath, tabRegEx, '%09');
1521-
return filepath;
1514+
if (!escapePathRegExp.test(filepath)) {
1515+
return filepath;
1516+
}
1517+
let result = '';
1518+
let last = 0;
1519+
for (let i = 0; i < filepath.length; i++) {
1520+
const point = filepath.charCodeAt(i);
1521+
if (point <= 13 || point === 37 || (!isWindows && point === 92)) {
1522+
const replacingChar = escapedPathChars[filepath[i]];
1523+
if (replacingChar !== undefined) {
1524+
result += `${filepath.slice(last, i)}${replacingChar}`;
1525+
last = i + 1;
1526+
}
1527+
}
1528+
}
1529+
1530+
if (last !== filepath.length) {
1531+
result += filepath.slice(last);
1532+
}
1533+
return result;
15221534
}
15231535

15241536
function pathToFileURL(filepath) {

0 commit comments

Comments
 (0)