From 5dbd2dfaff34f7f6bca54b6e97c0dcee89422aff Mon Sep 17 00:00:00 2001 From: D-Sketon <2055272094@qq.com> Date: Fri, 3 Oct 2025 19:21:11 +0800 Subject: [PATCH 1/2] perf: faster `encode_url` and `decode_url` --- lib/decode_url.ts | 11 +++++++++-- lib/encode_url.ts | 11 +++++++++-- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/lib/decode_url.ts b/lib/decode_url.ts index c1410e07..320b6f4e 100644 --- a/lib/decode_url.ts +++ b/lib/decode_url.ts @@ -1,8 +1,15 @@ -import { parse, format } from 'url'; +import { format } from 'url'; import { unescape } from 'querystring'; +const PROTOCOL_RE = /^[a-z0-9.+-]+:/i; + +const hasProtocolLikeNode = (str: unknown): boolean => { + if (typeof str !== 'string') throw new TypeError('url must be a string'); + return PROTOCOL_RE.test(str.trim()); +}; + const decodeURL = (str: string) => { - if (parse(str).protocol) { + if (hasProtocolLikeNode(str)) { const parsed = new URL(str); // Exit if input is a data url diff --git a/lib/encode_url.ts b/lib/encode_url.ts index 8934b2d1..75d7fda3 100644 --- a/lib/encode_url.ts +++ b/lib/encode_url.ts @@ -1,8 +1,15 @@ -import { parse, format } from 'url'; +import { format } from 'url'; import { unescape } from 'querystring'; +const PROTOCOL_RE = /^[a-z0-9.+-]+:/i; + +const hasProtocolLikeNode = (str: unknown): boolean => { + if (typeof str !== 'string') throw new TypeError('url must be a string'); + return PROTOCOL_RE.test(str.trim()); +}; + const encodeURL = (str: string) => { - if (parse(str).protocol) { + if (hasProtocolLikeNode(str)) { const parsed = new URL(str); // Exit if input is a data url From 37217713024bed5712830206408f63d0480b46b4 Mon Sep 17 00:00:00 2001 From: D-Sketon <2055272094@qq.com> Date: Mon, 13 Oct 2025 23:35:05 +0800 Subject: [PATCH 2/2] feat: rm regexp --- lib/decode_url.ts | 15 ++++++--------- lib/encode_url.ts | 15 ++++++--------- 2 files changed, 12 insertions(+), 18 deletions(-) diff --git a/lib/decode_url.ts b/lib/decode_url.ts index 320b6f4e..6d31db79 100644 --- a/lib/decode_url.ts +++ b/lib/decode_url.ts @@ -1,15 +1,12 @@ -import { format } from 'url'; +import { format, parse } from 'url'; import { unescape } from 'querystring'; -const PROTOCOL_RE = /^[a-z0-9.+-]+:/i; - -const hasProtocolLikeNode = (str: unknown): boolean => { - if (typeof str !== 'string') throw new TypeError('url must be a string'); - return PROTOCOL_RE.test(str.trim()); -}; - const decodeURL = (str: string) => { - if (hasProtocolLikeNode(str)) { + const index = str.indexOf(':'); + if (index < 0) { + return unescape(str); + } + if (parse(str.slice(0, index + 1)).protocol) { const parsed = new URL(str); // Exit if input is a data url diff --git a/lib/encode_url.ts b/lib/encode_url.ts index 75d7fda3..64705930 100644 --- a/lib/encode_url.ts +++ b/lib/encode_url.ts @@ -1,15 +1,12 @@ -import { format } from 'url'; +import { format, parse } from 'url'; import { unescape } from 'querystring'; -const PROTOCOL_RE = /^[a-z0-9.+-]+:/i; - -const hasProtocolLikeNode = (str: unknown): boolean => { - if (typeof str !== 'string') throw new TypeError('url must be a string'); - return PROTOCOL_RE.test(str.trim()); -}; - const encodeURL = (str: string) => { - if (hasProtocolLikeNode(str)) { + const index = str.indexOf(':'); + if (index < 0) { + return encodeURI(unescape(str)); + } + if (parse(str.slice(0, index + 1)).protocol) { const parsed = new URL(str); // Exit if input is a data url