Skip to content

Commit 6a96ac8

Browse files
vicbconico974
andauthored
perf(OpenNextResponse): do not store the chunks for streamed responses (#992)
Co-authored-by: conico974 <[email protected]>
1 parent c6e0005 commit 6a96ac8

File tree

2 files changed

+24
-15
lines changed

2 files changed

+24
-15
lines changed

.changeset/honest-lamps-smell.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
---
2+
"@opennextjs/aws": minor
3+
---
4+
5+
perf(OpenNextResponse): do not store the chunks for streamed responses
6+
7+
There is no need to store the chunks for streamed responses.
8+
Not storing the chunks allows saving memory.
9+
10+
BREAKING CHANGE: Note that `OpenNextHandler` will now return an empty body if your wrapper provides a `StreamCreator`
11+
This could break custom converters.

packages/open-next/src/http/openNextResponse.ts

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,13 @@ export class OpenNextNodeResponse extends Transform implements ServerResponse {
2020
statusCode!: number;
2121
statusMessage = "";
2222
headers: OutgoingHttpHeaders = {};
23-
private _cookies: string[] = [];
24-
private responseStream?: Writable;
2523
headersSent = false;
2624
_chunks: Buffer[] = [];
2725

26+
private _cookies: string[] = [];
27+
private responseStream?: Writable;
28+
private bodyLength = 0;
29+
2830
// To comply with the ServerResponse interface :
2931
strictContentLength = false;
3032
assignSocket(_socket: Socket): void {
@@ -282,16 +284,13 @@ export class OpenNextNodeResponse extends Transform implements ServerResponse {
282284
return Buffer.concat(this._chunks);
283285
}
284286

285-
getBodyLength(): number {
286-
let size = 0;
287-
for (const chunk of this._chunks) {
288-
size += chunk.length;
289-
}
290-
return size;
291-
}
292-
293287
private _internalWrite(chunk: any, encoding: BufferEncoding) {
294-
this._chunks.push(Buffer.from(chunk, encoding));
288+
const buffer = Buffer.from(chunk, encoding);
289+
this.bodyLength += buffer.length;
290+
if (!this.streamCreator) {
291+
// Do not keep chunks around for streamed responses
292+
this._chunks.push(buffer);
293+
}
295294
this.push(chunk, encoding);
296295
this.streamCreator?.onWrite?.();
297296
}
@@ -314,12 +313,11 @@ export class OpenNextNodeResponse extends Transform implements ServerResponse {
314313
this.flushHeaders();
315314
}
316315
// In some cases we might not have a store i.e. for example in the image optimization function
317-
// We may want to reconsider this in the future, it might be intersting to have access to this store everywhere
316+
// We may want to reconsider this in the future, it might be interesting to have access to this store everywhere
318317
globalThis.__openNextAls
319318
?.getStore()
320319
?.pendingPromiseRunner.add(this.onEnd(this.headers));
321-
const bodyLength = this.getBodyLength();
322-
this.streamCreator?.onFinish?.(bodyLength);
320+
this.streamCreator?.onFinish?.(this.bodyLength);
323321

324322
//This is only here because of aws broken streaming implementation.
325323
//Hopefully one day they will be able to give us a working streaming implementation in lambda for everyone
@@ -328,7 +326,7 @@ export class OpenNextNodeResponse extends Transform implements ServerResponse {
328326
//BE CAREFUL: Aws keeps rolling out broken streaming implementations even on accounts that had working ones before
329327
//This is not dependent on the node runtime used
330328
if (
331-
bodyLength === 0 &&
329+
this.bodyLength === 0 &&
332330
// We use an env variable here because not all aws account have the same behavior
333331
// On some aws accounts the response will hang if the body is empty
334332
// We are modifying the response body here, this is not a good practice

0 commit comments

Comments
 (0)