Skip to content

Commit 047844c

Browse files
authored
refactor(ssr): extract buffer resolving and resolvePortals (#771)
1 parent 20afd40 commit 047844c

File tree

1 file changed

+29
-29
lines changed

1 file changed

+29
-29
lines changed

packages/server-renderer/src/renderToString.ts

+29-29
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,11 @@ function createBuffer() {
6767
let hasAsync = false
6868
const buffer: SSRBuffer = []
6969
return {
70-
buffer,
71-
hasAsync() {
72-
return hasAsync
70+
getBuffer(): ResolvedSSRBuffer | Promise<ResolvedSSRBuffer> {
71+
// If the current component's buffer contains any Promise from async children,
72+
// then it must return a Promise too. Otherwise this is a component that
73+
// contains only sync children so we can avoid the async book-keeping overhead.
74+
return hasAsync ? Promise.all(buffer) : (buffer as ResolvedSSRBuffer)
7375
},
7476
push(item: SSRBufferItem) {
7577
const isStringItem = isString(item)
@@ -104,28 +106,19 @@ export async function renderToString(
104106
input: App | VNode,
105107
context: SSRContext = {}
106108
): Promise<string> {
107-
let buffer: ResolvedSSRBuffer
108109
if (isVNode(input)) {
109110
// raw vnode, wrap with app (for context)
110111
return renderToString(createApp({ render: () => input }), context)
111-
} else {
112-
// rendering an app
113-
const vnode = createVNode(input._component, input._props)
114-
vnode.appContext = input._context
115-
// provide the ssr context to the tree
116-
input.provide(ssrContextKey, context)
117-
buffer = await renderComponentVNode(vnode)
118112
}
119113

120-
// resolve portals
121-
if (context.__portalBuffers) {
122-
context.portals = context.portals || {}
123-
for (const key in context.__portalBuffers) {
124-
// note: it's OK to await sequentially here because the Promises were
125-
// created eagerly in parallel.
126-
context.portals[key] = unrollBuffer(await context.__portalBuffers[key])
127-
}
128-
}
114+
// rendering an app
115+
const vnode = createVNode(input._component, input._props)
116+
vnode.appContext = input._context
117+
// provide the ssr context to the tree
118+
input.provide(ssrContextKey, context)
119+
const buffer = await renderComponentVNode(vnode)
120+
121+
await resolvePortals(context)
129122

130123
return unrollBuffer(buffer)
131124
}
@@ -201,7 +194,7 @@ function renderComponentSubTree(
201194
instance: ComponentInternalInstance
202195
): ResolvedSSRBuffer | Promise<ResolvedSSRBuffer> {
203196
const comp = instance.type as Component
204-
const { buffer, push, hasAsync } = createBuffer()
197+
const { getBuffer, push } = createBuffer()
205198
if (isFunction(comp)) {
206199
renderVNode(push, renderComponentRoot(instance), instance)
207200
} else {
@@ -225,10 +218,7 @@ function renderComponentSubTree(
225218
)
226219
}
227220
}
228-
// If the current component's buffer contains any Promise from async children,
229-
// then it must return a Promise too. Otherwise this is a component that
230-
// contains only sync children so we can avoid the async book-keeping overhead.
231-
return hasAsync() ? Promise.all(buffer) : (buffer as ResolvedSSRBuffer)
221+
return getBuffer()
232222
}
233223

234224
function renderVNode(
@@ -349,7 +339,7 @@ function renderPortal(
349339
return []
350340
}
351341

352-
const { buffer, push, hasAsync } = createBuffer()
342+
const { getBuffer, push } = createBuffer()
353343
renderVNodeChildren(
354344
push,
355345
vnode.children as VNodeArrayChildren,
@@ -360,7 +350,17 @@ function renderPortal(
360350
] as SSRContext
361351
const portalBuffers =
362352
context.__portalBuffers || (context.__portalBuffers = {})
363-
portalBuffers[target] = hasAsync()
364-
? Promise.all(buffer)
365-
: (buffer as ResolvedSSRBuffer)
353+
354+
portalBuffers[target] = getBuffer()
355+
}
356+
357+
async function resolvePortals(context: SSRContext) {
358+
if (context.__portalBuffers) {
359+
context.portals = context.portals || {}
360+
for (const key in context.__portalBuffers) {
361+
// note: it's OK to await sequentially here because the Promises were
362+
// created eagerly in parallel.
363+
context.portals[key] = unrollBuffer(await context.__portalBuffers[key])
364+
}
365+
}
366366
}

0 commit comments

Comments
 (0)