chore: derive content-length from fixed response bodies in setResponse - #16794
Conversation
|
Install the latest version of pnpm add https://pkg.svelte.dev/@sveltejs/kit/c/44c0e5f63073bf257f37c9c4b540be6bff19ab66Open in |
🦋 Changeset detectedLatest commit: 44c0e5f The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
Noice, do you think it should be updated in other parts as well? also would the |
|
I think for that exact reason you've mentioned (no content-length headers) we've avoided switching away from it for now. |
1a5b9ac to
6ce4a9f
Compare
Response.json in runtime responses|
It seems a bit complicated for something that no longer gets rid of the need for |
|
You're right. I think there is a better redesign here. wip |
|
Lol didn't mean to make you doing a redesign😅 |
|
Yeah, I wasn't trying to do one either, unfortunately node has to always be in the way. A redesign was necessary to make this PR appealing. |
|
@ottomated I benchmarked this rework with autocannon, setResponse in isolation. small JSON ~30k req/s on both, 20KB bodies ~300 vs ~430 MB/s, 5MB bodies ~1GB/s on both. So yes, more performant: ~40% more throughput on page-sized responses, parity everywhere else! |
Rich-Harris
left a comment
There was a problem hiding this comment.
it's a shame that this adds some complexity but i don't see a simpler alternative
On Node,
setResponsestreams everyresponse.bodythrough a reader loop, so a response without a pre-computedcontent-lengthheader is served with chunked transfer encoding. That is why the runtime can't move off the deprecatedjson/texthelpers, whose only load-bearing job is stamping that header, and why a plainResponse.jsonreturned from an endpoint is served chunked today. Every other runtime derives the header from fixed bodies at serve time.setResponsenow races the body's first reads against asetImmediatedeadline before writing the head. A fixed body settles value-then-done on microtasks, so it is sent with a measuredcontent-length; a body that leaves a read pending is a genuine stream and goes through the existing streaming path unchanged, with its headers delayed by at most one tick. Nothing is added when the response already carries acontent-lengthor atransfer-encoding(proxied responses can carry the latter, and the pair would be invalid). Same approach as hono's node-server.json/textare untouched. Retiring them internally becomes a follow-up; its one catch is thehttp.response.body.sizespan attribute, which reads thecontent-lengthheader.#16804 is stacked on this.