Skip to content

Commit 1173315

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

File tree

1 file changed

+37
-34
lines changed

1 file changed

+37
-34
lines changed

lib/url.js

Lines changed: 37 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ const {
2727
ObjectAssign,
2828
ObjectKeys,
2929
StringPrototypeCharCodeAt,
30+
StringPrototypeIndexOf,
31+
StringPrototypeReplaceAll,
32+
StringPrototypeSlice,
3033
decodeURIComponent,
3134
} = primordials;
3235

@@ -637,6 +640,10 @@ Url.prototype.format = function format() {
637640
}
638641

639642
let protocol = this.protocol || '';
643+
if (protocol && StringPrototypeCharCodeAt(protocol, protocol.length - 1) !== 58 /* : */) {
644+
protocol += ':';
645+
}
646+
640647
let pathname = this.pathname || '';
641648
let hash = this.hash || '';
642649
let host = '';
@@ -646,7 +653,7 @@ Url.prototype.format = function format() {
646653
host = auth + this.host;
647654
} else if (this.hostname) {
648655
host = auth + (
649-
this.hostname.includes(':') && !isIpv6Hostname(this.hostname) ?
656+
StringPrototypeIndexOf(this.hostname, ':') !== -1 && !isIpv6Hostname(this.hostname) ?
650657
'[' + this.hostname + ']' :
651658
this.hostname
652659
);
@@ -658,59 +665,55 @@ Url.prototype.format = function format() {
658665
if (this.query !== null && typeof this.query === 'object') {
659666
query = querystring.stringify(this.query);
660667
}
661-
662668
let search = this.search || (query && ('?' + query)) || '';
663669

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';
670+
if (StringPrototypeIndexOf(pathname, '#') !== -1 || StringPrototypeIndexOf(pathname, '?') !== -1) {
671+
let newPathname = '';
672+
let lastPos = 0;
673+
const len = pathname.length;
674+
for (let i = 0; i < len; i++) {
675+
const code = StringPrototypeCharCodeAt(pathname, i);
676+
if (code === CHAR_HASH || code === CHAR_QUESTION_MARK) {
677+
if (i > lastPos) {
678+
newPathname += StringPrototypeSlice(pathname, lastPos, i);
679+
}
680+
newPathname += (code === CHAR_HASH ? '%23' : '%3F');
681681
lastPos = i + 1;
682-
break;
682+
}
683683
}
684-
}
685-
if (lastPos > 0) {
686-
if (lastPos !== pathname.length)
687-
pathname = newPathname + pathname.slice(lastPos);
688-
else
689-
pathname = newPathname;
684+
if (lastPos < len) {
685+
newPathname += StringPrototypeSlice(pathname, lastPos);
686+
}
687+
pathname = newPathname;
690688
}
691689

692690
// Only the slashedProtocols get the //. Not mailto:, xmpp:, etc.
693691
// unless they had them to begin with.
694692
if (this.slashes || slashedProtocol.has(protocol)) {
695693
if (this.slashes || host) {
696-
if (pathname && pathname.charCodeAt(0) !== CHAR_FORWARD_SLASH)
694+
if (pathname && StringPrototypeCharCodeAt(pathname, 0) !== CHAR_FORWARD_SLASH)
697695
pathname = '/' + pathname;
698696
host = '//' + host;
699697
} 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 */) {
698+
StringPrototypeCharCodeAt(protocol, 0) === 102/* f */ &&
699+
StringPrototypeCharCodeAt(protocol, 1) === 105/* i */ &&
700+
StringPrototypeCharCodeAt(protocol, 2) === 108/* l */ &&
701+
StringPrototypeCharCodeAt(protocol, 3) === 101/* e */) {
704702
host = '//';
705703
}
706704
}
707705

708-
search = search.replaceAll('#', '%23');
706+
// Escape '#' in search.
707+
if (StringPrototypeIndexOf(search, '#') !== -1) {
708+
search = StringPrototypeReplaceAll(search, '#', '%23');
709+
}
709710

710-
if (hash && hash.charCodeAt(0) !== CHAR_HASH)
711+
if (hash && StringPrototypeCharCodeAt(hash, 0) !== CHAR_HASH) {
711712
hash = '#' + hash;
712-
if (search && search.charCodeAt(0) !== CHAR_QUESTION_MARK)
713+
}
714+
if (search && StringPrototypeCharCodeAt(search, 0) !== CHAR_QUESTION_MARK) {
713715
search = '?' + search;
716+
}
714717

715718
return protocol + host + pathname + search + hash;
716719
};

0 commit comments

Comments
 (0)