Skip to content

Commit

Permalink
url: improve URLSearchParams creation performance
Browse files Browse the repository at this point in the history
  • Loading branch information
anonrig committed Mar 21, 2023
1 parent 1640aeb commit 7ed296b
Showing 1 changed file with 14 additions and 24 deletions.
38 changes: 14 additions & 24 deletions lib/internal/url.js
Expand Up @@ -150,52 +150,45 @@ function isURLSearchParams(self) {
}

class URLSearchParams {
[searchParams] = [];

// "associated url object"
[context] = null;

// URL Standard says the default value is '', but as undefined and '' have
// the same result, undefined is used to prevent unnecessary parsing.
// Default parameter is necessary to keep URLSearchParams.length === 0 in
// accordance with Web IDL spec.
constructor(init = undefined) {
if (init === null || init === undefined) {
this[searchParams] = [];
if (init == null) {
// Do nothing
} else if (typeof init === 'object' || typeof init === 'function') {
const method = init[SymbolIterator];
if (method === this[SymbolIterator]) {
// While the spec does not have this branch, we can use it as a
// shortcut to avoid having to go through the costly generic iterator.
const childParams = init[searchParams];
this[searchParams] = childParams.slice();
} else if (method !== null && method !== undefined) {
} else if (method != null) {
if (typeof method !== 'function') {
throw new ERR_ARG_NOT_ITERABLE('Query pairs');
}

// Sequence<sequence<USVString>>
// Note: per spec we have to first exhaust the lists then process them
const pairs = [];
for (const pair of init) {
if ((typeof pair !== 'object' && typeof pair !== 'function') ||
pair === null ||
typeof pair[SymbolIterator] !== 'function') {
// If innerSequence's size is not 2, then throw a TypeError.
if (pair == null || (typeof pair !== 'object' && typeof pair !== 'function') ||
typeof pair[SymbolIterator] !== 'function' || pair.length !== 2) {
throw new ERR_INVALID_TUPLE('Each query pair', '[name, value]');
}
const convertedPair = [];
for (const element of pair)
ArrayPrototypePush(convertedPair, toUSVString(element));
ArrayPrototypePush(pairs, convertedPair);
}

this[searchParams] = [];
for (const pair of pairs) {
if (pair.length !== 2) {
throw new ERR_INVALID_TUPLE('Each query pair', '[name, value]');
}
ArrayPrototypePush(this[searchParams], pair[0], pair[1]);
// Append (innerSequence[0], innerSequence[1]) to querys list.
ArrayPrototypePush(this[searchParams], toUSVString(pair[0]), toUSVString(pair[1]));
}
} else {
// Record<USVString, USVString>
// Need to use reflection APIs for full spec compliance.
const visited = {};
this[searchParams] = [];
const keys = ReflectOwnKeys(init);
for (let i = 0; i < keys.length; i++) {
const key = keys[i];
Expand All @@ -217,13 +210,10 @@ class URLSearchParams {
}
}
} else {
// USVString
// https://url.spec.whatwg.org/#dom-urlsearchparams-urlsearchparams
init = toUSVString(init);
this[searchParams] = init ? parseParams(init) : [];
}

// "associated url object"
this[context] = null;
}

[inspect.custom](recurseTimes, ctx) {
Expand Down

0 comments on commit 7ed296b

Please sign in to comment.