Skip to content

Commit bdd5eb4

Browse files
committed
url: improve performance of the format function
1 parent 1d8593e commit bdd5eb4

File tree

1 file changed

+36
-34
lines changed

1 file changed

+36
-34
lines changed

lib/url.js

Lines changed: 36 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ const {
2727
ObjectAssign,
2828
ObjectKeys,
2929
StringPrototypeCharCodeAt,
30+
StringPrototypeIndexOf,
31+
StringPrototypeSlice,
3032
decodeURIComponent,
3133
} = primordials;
3234

@@ -637,6 +639,10 @@ Url.prototype.format = function format() {
637639
}
638640

639641
let protocol = this.protocol || '';
642+
if (protocol && StringPrototypeCharCodeAt(protocol, protocol.length - 1) !== 58 /* : */) {
643+
protocol += ':';
644+
}
645+
640646
let pathname = this.pathname || '';
641647
let hash = this.hash || '';
642648
let host = '';
@@ -646,7 +652,7 @@ Url.prototype.format = function format() {
646652
host = auth + this.host;
647653
} else if (this.hostname) {
648654
host = auth + (
649-
this.hostname.includes(':') && !isIpv6Hostname(this.hostname) ?
655+
StringPrototypeIndexOf(this.hostname, ':') !== -1 && !isIpv6Hostname(this.hostname) ?
650656
'[' + this.hostname + ']' :
651657
this.hostname
652658
);
@@ -658,59 +664,55 @@ Url.prototype.format = function format() {
658664
if (this.query !== null && typeof this.query === 'object') {
659665
query = querystring.stringify(this.query);
660666
}
661-
662667
let search = this.search || (query && ('?' + query)) || '';
663668

664-
if (protocol && protocol.charCodeAt(protocol.length - 1) !== 58/* : */)
665-
protocol += ':';
666-
667-
let newPathname = '';
668-
let lastPos = 0;
669-
for (let i = 0; i < pathname.length; ++i) {
670-
switch (pathname.charCodeAt(i)) {
671-
case CHAR_HASH:
672-
if (i - lastPos > 0)
673-
newPathname += pathname.slice(lastPos, i);
674-
newPathname += '%23';
675-
lastPos = i + 1;
676-
break;
677-
case CHAR_QUESTION_MARK:
678-
if (i - lastPos > 0)
679-
newPathname += pathname.slice(lastPos, i);
680-
newPathname += '%3F';
669+
if (StringPrototypeIndexOf(pathname, '#') !== -1 || StringPrototypeIndexOf(pathname, '?') !== -1) {
670+
let newPathname = '';
671+
let lastPos = 0;
672+
const len = pathname.length;
673+
for (let i = 0; i < len; i++) {
674+
const code = StringPrototypeCharCodeAt(pathname, i);
675+
if (code === CHAR_HASH || code === CHAR_QUESTION_MARK) {
676+
if (i > lastPos) {
677+
newPathname += StringPrototypeSlice(pathname, lastPos, i);
678+
}
679+
newPathname += (code === CHAR_HASH ? '%23' : '%3F');
681680
lastPos = i + 1;
682-
break;
681+
}
683682
}
684-
}
685-
if (lastPos > 0) {
686-
if (lastPos !== pathname.length)
687-
pathname = newPathname + pathname.slice(lastPos);
688-
else
689-
pathname = newPathname;
683+
if (lastPos < len) {
684+
newPathname += StringPrototypeSlice(pathname, lastPos);
685+
}
686+
pathname = newPathname;
690687
}
691688

692689
// Only the slashedProtocols get the //. Not mailto:, xmpp:, etc.
693690
// unless they had them to begin with.
694691
if (this.slashes || slashedProtocol.has(protocol)) {
695692
if (this.slashes || host) {
696-
if (pathname && pathname.charCodeAt(0) !== CHAR_FORWARD_SLASH)
693+
if (pathname && StringPrototypeCharCodeAt(pathname, 0) !== CHAR_FORWARD_SLASH)
697694
pathname = '/' + pathname;
698695
host = '//' + host;
699696
} else if (protocol.length >= 4 &&
700-
protocol.charCodeAt(0) === 102/* f */ &&
701-
protocol.charCodeAt(1) === 105/* i */ &&
702-
protocol.charCodeAt(2) === 108/* l */ &&
703-
protocol.charCodeAt(3) === 101/* e */) {
697+
StringPrototypeCharCodeAt(protocol, 0) === 102/* f */ &&
698+
StringPrototypeCharCodeAt(protocol, 1) === 105/* i */ &&
699+
StringPrototypeCharCodeAt(protocol, 2) === 108/* l */ &&
700+
StringPrototypeCharCodeAt(protocol, 3) === 101/* e */) {
704701
host = '//';
705702
}
706703
}
707704

708-
search = search.replaceAll('#', '%23');
705+
// Escape '#' in search.
706+
if (search.indexOf('#') !== -1) {
707+
search = search.replace(/#/g, '%23');
708+
}
709709

710-
if (hash && hash.charCodeAt(0) !== CHAR_HASH)
710+
if (hash && StringPrototypeCharCodeAt(hash, 0) !== CHAR_HASH) {
711711
hash = '#' + hash;
712-
if (search && search.charCodeAt(0) !== CHAR_QUESTION_MARK)
712+
}
713+
if (search && StringPrototypeCharCodeAt(search, 0) !== CHAR_QUESTION_MARK) {
713714
search = '?' + search;
715+
}
714716

715717
return protocol + host + pathname + search + hash;
716718
};

0 commit comments

Comments
 (0)