Repository navigation
perf: relay untouched net.fetch responses from protocol.handle without pumping them through JS - #53378
Merged
Conversation
…t pumping them through JS (#52953) * perf: relay untouched net.fetch responses from protocol.handle without pumping them through JS protocol.handle(scheme, req => net.fetch(...)) is the documented way to serve an app's own files from a custom scheme and to proxy a remote origin through one, and every byte of such a response crossed the browser main thread twice: SimpleURLLoader's chunks were copied into ArrayBuffers for an IncomingMessage, wrapped into a web ReadableStream for the Response, unwrapped again with Readable.fromWeb and written back into a mojo pipe by NodeStreamLoader in 64 KB slices. When a handler returns the Response net.fetch produced with its body still untouched (the exact stream net.fetch created, not read, locked, cloned or replaced), protocol.handle now tells the underlying SimpleURLLoaderWrapper to stop handing chunks to JS, collects whatever JS had already pulled as a prefix, and passes the client end to the wrapper, which writes prefix and remainder straight into the response pipe and completes the client with the request's outcome. Status and headers of the returned Response (including ones the handler set) are used as before; anything else - a re-wrapped or re-created Response, a body the handler started reading, Response.error() - keeps the existing path. The response pipe grows to the upstream's declared length (up to the network service default) but never below mojo's default. Works for any scheme net.fetch can load. Renderer fetch() through such a handler, release build, medians of interleaved fresh-process runs: forwarding to file:// 16 MB 40.0 -> 24.1 ms, 1 MB 4.5 -> 3.8 ms, 64 KB 2.0 -> 1.9 ms; forwarding to a local http server (cache: 'no-store') 16 MB 48.2 -> 24.2 ms, 1 MB 4.0 -> 3.3 ms, 64 KB unchanged. With the HTTP cache writing the proxied body through, the cache write dominates either way (16 MB ~480 ms on this disk). * refactor: move response body holding/relaying out of SimpleURLLoaderWrapper Review follow-up: SimpleURLLoaderWrapper no longer tracks relay state itself. A ResponseBody object is the SimpleURLLoader stream consumer; it hands chunks to its delegate (the wrapper, which emits them to JS) until held, and once RelayTo() gives it a destination it writes the held and all further chunks into that client's data pipe and completes the client when the request completes. The wrapper keeps only the JS-facing events and request lifetime. * fix: complete relayed responses whose fetch finished before hold() ResponseBody::OnComplete() returned before recording the result when the body had not been held yet, so a handler that awaited between net.fetch() and returning the response handed RelayTo() a finished request with no result to complete the client with, and the load hung. Record the result unconditionally, and when JS has already drained the whole body before the relay decision, answer with that data instead of a native relay. Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
6 tasks done
MarshallOfSound
approved these changes
Sep 3, 2026
MarshallOfSound
deleted the
trop/44-x-y-bp-perf-relay-untouched-net-fetch-responses-from-protocol-handle-without-pumping-them-through-js-1788291925207
branch
September 3, 2026 17:16
|
Release Notes Persisted
|
renovate Bot
added a commit
to cigaleapp/cigale
that referenced
this pull request
Sep 13, 2026
##### [v44.2.0](https://github.com/electron/electron/releases/tag/v44.2.0) ### Release Notes for v44.2.0 #### Fixes - Fixed a pending read on a `net.request` chunked upload stream inside a protocol handler never settling when the request failed or was aborted. [#53373](electron/electron#53373) <sup>(Also in [43](electron/electron#53374), [45](https://github.com/electron/electron/pull/53368))</sup> - Fixed a potential crash when using `menu.popup` with a frame from an offscreen rendered window. [#53362](electron/electron#53362) <sup>(Also in [43](https://github.com/electron/electron/pull/53432))</sup> - Fixed an intermittent crash (access violation) on Windows when an ASAR integrity violation is detected, so the process now exits with code 1 as intended. [#53455](electron/electron#53455) <sup>(Also in [43](electron/electron#53456), [45](https://github.com/electron/electron/pull/53438))</sup> - Fixed application crash after a large number of IPC messages from renderers. [#53417](electron/electron#53417) <sup>(Also in [42](electron/electron#53419), [43](electron/electron#53420), [45](https://github.com/electron/electron/pull/53418))</sup> - Fixed native addons deriving from `node::ObjectWrap` aborting during garbage collection on Node.js 24.19.0 and later. [#53392](electron/electron#53392) <sup>(Also in [42](electron/electron#53394), [43](electron/electron#53393), [45](https://github.com/electron/electron/pull/53391))</sup> #### Other Changes - Backported fixes from upstream ANGLE, Chromium, Skia and V8. [#53479](electron/electron#53479) - Improved throughput of responses that `protocol.handle` handlers return straight from `net.fetch`. [#53378](electron/electron#53378) - Updated Chromium to 152.0.7977.76. [#53382](electron/electron#53382) - Updated Node.js to v24.20.0. [#53250](electron/electron#53250) ##### [v44.1.1](https://github.com/electron/electron/releases/tag/v44.1.1) ### Release Notes for v44.1.1 #### Fixes - Fixed `chrome.tabs.query()` returning tab `url` and `title` to extensions without the `tabs` permission or host access, aligning with `tabs.get`. [#53354](electron/electron#53354) <sup>(Also in [42](electron/electron#53355), [43](electron/electron#53356), [45](https://github.com/electron/electron/pull/53353))</sup> - Fixed a renderer crash when an array with a throwing property getter is passed across `contextBridge`, and several main/utility-process crashes when option objects passed to Electron APIs contain throwing accessors or Proxy traps. [#53331](electron/electron#53331) <sup>(Also in [42](electron/electron#53329), [43](https://github.com/electron/electron/pull/53330))</sup> - Fixed an intermittent crash at startup on Linux caused by a race between Pango and the main thread initializing fontconfig. [#53340](electron/electron#53340) <sup>(Also in [43](electron/electron#53339), [45](https://github.com/electron/electron/pull/53338))</sup> - Fixed an issue where an exception thrown by a property getter on an object passed through `contextBridge` was swallowed instead of being thrown back to the caller. [#53335](electron/electron#53335) <sup>(Also in [43](electron/electron#53334), [45](https://github.com/electron/electron/pull/53297))</sup> - Fixed main process crashes when navigating to `http://accessibility/` or `http://devtools/`, when an extension background page used `navigator.mediaDevices`, and when calling `SerialPort.forget()` for a disconnected device. [#53333](electron/electron#53333) <sup>(Also in [43](electron/electron#53332), [45](https://github.com/electron/electron/pull/53325))</sup> - Fixed the PDF viewer failing to save an edited PDF with `NotAllowedError: Third party iframes are not allowed to show a file picker`. [#53328](electron/electron#53328) <sup>(Also in [43](electron/electron#53327), [45](https://github.com/electron/electron/pull/53326))</sup>
gwennlbh
pushed a commit
to cigaleapp/cigale
that referenced
this pull request
Sep 14, 2026
##### [v44.2.0](https://github.com/electron/electron/releases/tag/v44.2.0) ### Release Notes for v44.2.0 #### Fixes - Fixed a pending read on a `net.request` chunked upload stream inside a protocol handler never settling when the request failed or was aborted. [#53373](electron/electron#53373) <sup>(Also in [43](electron/electron#53374), [45](https://github.com/electron/electron/pull/53368))</sup> - Fixed a potential crash when using `menu.popup` with a frame from an offscreen rendered window. [#53362](electron/electron#53362) <sup>(Also in [43](https://github.com/electron/electron/pull/53432))</sup> - Fixed an intermittent crash (access violation) on Windows when an ASAR integrity violation is detected, so the process now exits with code 1 as intended. [#53455](electron/electron#53455) <sup>(Also in [43](electron/electron#53456), [45](https://github.com/electron/electron/pull/53438))</sup> - Fixed application crash after a large number of IPC messages from renderers. [#53417](electron/electron#53417) <sup>(Also in [42](electron/electron#53419), [43](electron/electron#53420), [45](https://github.com/electron/electron/pull/53418))</sup> - Fixed native addons deriving from `node::ObjectWrap` aborting during garbage collection on Node.js 24.19.0 and later. [#53392](electron/electron#53392) <sup>(Also in [42](electron/electron#53394), [43](electron/electron#53393), [45](https://github.com/electron/electron/pull/53391))</sup> #### Other Changes - Backported fixes from upstream ANGLE, Chromium, Skia and V8. [#53479](electron/electron#53479) - Improved throughput of responses that `protocol.handle` handlers return straight from `net.fetch`. [#53378](electron/electron#53378) - Updated Chromium to 152.0.7977.76. [#53382](electron/electron#53382) - Updated Node.js to v24.20.0. [#53250](electron/electron#53250) ##### [v44.1.1](https://github.com/electron/electron/releases/tag/v44.1.1) ### Release Notes for v44.1.1 #### Fixes - Fixed `chrome.tabs.query()` returning tab `url` and `title` to extensions without the `tabs` permission or host access, aligning with `tabs.get`. [#53354](electron/electron#53354) <sup>(Also in [42](electron/electron#53355), [43](electron/electron#53356), [45](https://github.com/electron/electron/pull/53353))</sup> - Fixed a renderer crash when an array with a throwing property getter is passed across `contextBridge`, and several main/utility-process crashes when option objects passed to Electron APIs contain throwing accessors or Proxy traps. [#53331](electron/electron#53331) <sup>(Also in [42](electron/electron#53329), [43](https://github.com/electron/electron/pull/53330))</sup> - Fixed an intermittent crash at startup on Linux caused by a race between Pango and the main thread initializing fontconfig. [#53340](electron/electron#53340) <sup>(Also in [43](electron/electron#53339), [45](https://github.com/electron/electron/pull/53338))</sup> - Fixed an issue where an exception thrown by a property getter on an object passed through `contextBridge` was swallowed instead of being thrown back to the caller. [#53335](electron/electron#53335) <sup>(Also in [43](electron/electron#53334), [45](https://github.com/electron/electron/pull/53297))</sup> - Fixed main process crashes when navigating to `http://accessibility/` or `http://devtools/`, when an extension background page used `navigator.mediaDevices`, and when calling `SerialPort.forget()` for a disconnected device. [#53333](electron/electron#53333) <sup>(Also in [43](electron/electron#53332), [45](https://github.com/electron/electron/pull/53325))</sup> - Fixed the PDF viewer failing to save an edited PDF with `NotAllowedError: Third party iframes are not allowed to show a file picker`. [#53328](electron/electron#53328) <sup>(Also in [43](electron/electron#53327), [45](https://github.com/electron/electron/pull/53326))</sup> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
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.
Backport of #52953
See that PR for details.
Notes: Improved throughput of responses that
protocol.handlehandlers return straight fromnet.fetch.