stream: speed up WHATWG web streams - #65273
Open
anonrig wants to merge 3 commits into
Open
Conversation
Collaborator
|
Review requested:
|
Avoid per-chunk async wrappers for sync pull/write/start, fill default readable queues in pipeTo, and complete pipeTo writes without one microtask per chunk. Add a native webstreams binding with a Fast API isNonThenable check on the data plane and a memcpy clone for byte views. Empty stream construction skips redundant validation and lazily creates the writable AbortController, materializing it on abort() so controller.signal still reflects the abort reason. Assisted-by: Grok Signed-off-by: Yagiz Nizipli <yagiz@nizipli.com>
Declare isNonThenable and cloneAsUint8Array on the new webstreams binding and register it in InternalBindingMap. Assisted-by: Grok Signed-off-by: Yagiz Nizipli <yagiz@nizipli.com>
anonrig
force-pushed
the
stream-speed-up-webstreams
branch
from
August 13, 2026 23:23
6a3f89b to
c796760
Compare
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #65273 +/- ##
==========================================
+ Coverage 90.31% 90.33% +0.02%
==========================================
Files 751 752 +1
Lines 249840 250222 +382
Branches 47180 47259 +79
==========================================
+ Hits 225645 226041 +396
+ Misses 15587 15572 -15
- Partials 8608 8609 +1
🚀 New features to boost your workflow:
|
jasnell
reviewed
Aug 14, 2026
jasnell
reviewed
Aug 14, 2026
jasnell
reviewed
Aug 14, 2026
jasnell
reviewed
Aug 14, 2026
jasnell
reviewed
Aug 14, 2026
jasnell
reviewed
Aug 14, 2026
jasnell
reviewed
Aug 14, 2026
Member
|
Defensively marking this semver-major. If you can show that the optimization does not change observable behavior, that can be dropped, but the change in microtask timing from one pull to the next is likely observable. |
jasnell
reviewed
Aug 14, 2026
Member
Author
|
@jasnell I believe |
Contributor
|
Benchmark GHA (webstreams): https://github.com/nodejs/node/actions/runs/31808780686 |
anonrig
force-pushed
the
stream-speed-up-webstreams
branch
from
August 14, 2026 17:54
8ce1778 to
27c4cf3
Compare
Defer the default controller on new ReadableStream() until first use. Settle non-thenable pull/write with Promise.resolve().then so a throw in the fulfillment callback is an unhandled rejection, as on the promise path. Share a single no-op algorithm, format the native binding, and cover Proxy thenables. Re-run configure on the benchmark CI merge-commit build so new sources such as src/node_webstreams.cc are linked. Assisted-by: Grok Signed-off-by: Yagiz Nizipli <yagiz@nizipli.com>
anonrig
force-pushed
the
stream-speed-up-webstreams
branch
from
August 14, 2026 18:09
27c4cf3 to
1cf7319
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Behavior-preserving performance work on
node:stream/web. Specorchestration and brand checks stay in JS; the per-chunk data plane
drops Promise/microtask churn for the common sync pull/write case
and gets a small native helper on the hot path.
asyncwrappers on sync source/sink algorithms.createPromiseCallback*now calls the user function and returnsthe raw result. Non-thenable results settle via
queueMicrotask(same position as
Promise.resolve().then) instead of allocatinga Promise per pull/write/start.
pipeTofills a default readable queue from sync pulls andstill batches already-queued chunks into the destination. Further
spec pull-fulfillment (tee, WPT) stays one pull per microtask.
the fulfillment turn. Regular
writer.write()keeps the specone-completion-per-microtask order.
internalBinding('webstreams'): Fast APIisNonThenable()on every pull/write/start result, andcloneAsUint8Array()as a single memcpy for byte-stream / teeclones.
new ReadableStream()/new WritableStream()skipvalidateObjecton the shared emptysentinels. The writable
AbortControlleris created lazily andmaterialized on
abort(), socontroller.signalobserved afterabort is still aborted with that reason.
Public constructors, methods, and WHATWG Streams behavior
(backpressure, BYOB, pipeTo, tee, errors, transfer) are unchanged.
Benchmarks
benchmark/compare.js --runs 10of the in-repowebstreams/suiteon the same machine, same
out/Release/nodefamily (pre-changebinary vs this tree). Rates are ops/sec.
Hot-path geometric mean of
new/oldacross all configs ofpipe-to.js,readable-read.js,readable-read-buffered.js,creation.js,readable-async-iterator.js, andtee.js:1.94x (32 configs). Full suite including
js_transfer.js:1.84x (35 configs). No config has
mean(new)/mean(old) < 1.0(min 1.03 on
js_transferReadableStream).Tests
test/wpt/test-streams.jstest/parallel/test-whatwg-readable*,writable*,transform*,webstreams*,test-webstreams*,test-global-webstreams.jstest/parallel/test-whatwg-webstreams-hotpath.js(publicread()/pipeTo, native helpers, abort-before-signal)test-whatwg-writablestream.jsAI assistance
This change was developed with assistance from Grok. I reviewed,
tested, and take responsibility for the submitted code.