Skip to content

url: speed up WHATWG URL parsing - #65361

Open
anonrig wants to merge 1 commit into
nodejs:mainfrom
anonrig:cursor/url-parse-performance-603e
Open

url: speed up WHATWG URL parsing#65361
anonrig wants to merge 1 commit into
nodejs:mainfrom
anonrig:cursor/url-parse-performance-603e

Conversation

@anonrig

@anonrig anonrig commented Aug 18, 2026

Copy link
Copy Markdown
Member

Speeds up new URL() / URL.parse() on the common path: already-serialized ASCII hrefs.

The binding currently always:

  1. Copies the V8 string into a UTF-8 buffer (Utf8Value)
  2. Parses with Ada
  3. Allocates a new V8 string from href, even when it is byte-identical to the input

Typical URLs (https://example.com/path, the whatwg-url-parse benchmark corpus) are one-byte ASCII and already in serialized form. This change:

  • Parses one-byte ASCII inputs in place via v8::String::ValueView (no UTF-8 copy)
  • Returns the original V8 string when href == input (no second string allocation)
  • Avoids copying the base URL into a temporary std::string just to parse it
  • Applies the same in-place parse to update() (setters re-parse an already-serialized href)
  • Delays URLContext allocation until parse finishes, and initializes it in one shot from urlComponents
  • Skips `${input}` when the value is already a string

Non-ASCII inputs still go through Utf8Value. Those results are never reused as the original string, because UTF-8 conversion may replace unpaired surrogates.

Benchmark

Same machine, Release build, benchmark/url/whatwg-url-parse.js e=12. Repeated runs:

Config Before (ops/s) After (ops/s) Change
short / no base 7.82M 9.29M +19%
long / no base 2.50M 2.75M +10%
short / with base 2.94M 3.39M +15%

dot (needs path normalization, so a new href string) is unchanged.

Tests

  • test/parallel/test-whatwg-url-*.js and test-url-*.js: 54 pass, 1 skip
  • WPT url: 5107 pass, 0 unexpected failures
  • New test/parallel/test-whatwg-url-parse-fast-path.js covers already-serialized ASCII hrefs, trailing-slash and dot-segment normalization, base resolution, non-string input, invalid input, unpaired surrogates, IDN, and setters

Assisted-by: Cursor

@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

Review requested:

  • @nodejs/url

@nodejs-github-bot nodejs-github-bot added c++ Issues and PRs that require attention from people who are familiar with C++. needs-ci PRs that need a full CI run. whatwg-url Issues and PRs related to the WHATWG URL implementation. labels Aug 18, 2026
@anonrig
anonrig requested review from jasnell and mcollina August 18, 2026 01:33
@codecov

codecov Bot commented Aug 18, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 97.14286% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 90.13%. Comparing base (13fcd6f) to head (fa5ca3f).
⚠️ Report is 10 commits behind head on main.

Files with missing lines Patch % Lines
src/node_url.cc 93.47% 0 Missing and 3 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #65361      +/-   ##
==========================================
- Coverage   91.85%   90.13%   -1.73%     
==========================================
  Files         400      752     +352     
  Lines      178855   251898   +73043     
  Branches    27319    47378   +20059     
==========================================
+ Hits       164283   227037   +62754     
- Misses      14243    16185    +1942     
- Partials      329     8676    +8347     
Files with missing lines Coverage Δ
lib/internal/url.js 93.28% <100.00%> (+13.12%) ⬆️
src/node_url.cc 79.30% <93.47%> (ø)

... and 482 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@jasnell jasnell left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AI agents are not permitted to Signed-off-by

@mcollina mcollina left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@cursor
cursor Bot force-pushed the cursor/url-parse-performance-603e branch from b9884e1 to a66b5bc Compare August 18, 2026 11:39
@anonrig

anonrig commented Aug 18, 2026

Copy link
Copy Markdown
Member Author

Removed the Signed-off-by trailer from the commit(s). An AI agent cannot attest the DCO.

@cursor
cursor Bot force-pushed the cursor/url-parse-performance-603e branch from a66b5bc to 39c4db7 Compare August 18, 2026 12:49
Parse one-byte ASCII inputs in place instead of copying them into a
UTF-8 buffer, and reuse the original V8 string when the serialized
href is unchanged. Delay URLContext allocation until parse finishes
and skip ToString when the input is already a string.

Signed-off-by: Yagiz Nizipli <yagiz@nizipli.com>
Assisted-by: Cursor
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
@cursor
cursor Bot force-pushed the cursor/url-parse-performance-603e branch 2 times, most recently from fa5ca3f to ed31ad0 Compare August 18, 2026 18:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

c++ Issues and PRs that require attention from people who are familiar with C++. needs-ci PRs that need a full CI run. whatwg-url Issues and PRs related to the WHATWG URL implementation.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants