From 55c063eaac799b451c640e53a7c1373b9ba775e3 Mon Sep 17 00:00:00 2001 From: Jiachi Liu Date: Wed, 9 Mar 2022 12:06:37 +0100 Subject: [PATCH] Delay prefix flushing (#35170) Only happened with SSR without suspense case Similar reason to #34474, the prefix (script parts) might be flushed during the render stream causing bad HTML. Use the same tricky to delay the prefix flushing #### Expected ```html
content
``` #### Observed ```html
... >content
``` Test sample: https://next-react-server-components-r5xocii9r-huozhi.vercel.app/ssr --- packages/next/server/render.tsx | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/packages/next/server/render.tsx b/packages/next/server/render.tsx index d2e68b23669f072..b98af06fabdabe7 100644 --- a/packages/next/server/render.tsx +++ b/packages/next/server/render.tsx @@ -1820,17 +1820,25 @@ function createPrefixStream( prefix: string ): TransformStream { let prefixFlushed = false + let prefixPrefixFlushFinished: Promise | null = null return createTransformStream({ transform(chunk, controller) { + controller.enqueue(chunk) if (!prefixFlushed && prefix) { prefixFlushed = true - controller.enqueue(chunk) - controller.enqueue(encodeText(prefix)) - } else { - controller.enqueue(chunk) + prefixPrefixFlushFinished = new Promise((res) => { + // NOTE: streaming flush + // Enqueue prefix part before the major chunks are enqueued so that + // prefix won't be flushed too early to interrupt the data stream + setTimeout(() => { + controller.enqueue(encodeText(prefix)) + res() + }) + }) } }, flush(controller) { + if (prefixPrefixFlushFinished) return prefixPrefixFlushFinished if (!prefixFlushed && prefix) { prefixFlushed = true controller.enqueue(encodeText(prefix)) @@ -1850,6 +1858,7 @@ function createInlineDataStream( if (!dataStreamFinished) { const dataStreamReader = dataStream.getReader() + // NOTE: streaming flush // We are buffering here for the inlined data stream because the // "shell" stream might be chunkenized again by the underlying stream // implementation, e.g. with a specific high-water mark. To ensure it's