-
Notifications
You must be signed in to change notification settings - Fork 0
RFC: implement multi-head SSR #241
Copy link
Copy link
Open
Labels
[STAGE-2] incomplete implementationRemove this label when implementation is completeRemove this label when implementation is complete[STAGE-2] not fully covered by tests yetRemove this label when tests are verified to cover the implementationRemove this label when tests are verified to cover the implementation[STAGE-2] unresolved discussions leftRemove this label when all critical discussions are resolved on the issueRemove this label when all critical discussions are resolved on the issue[STAGE-3] docs changes not added yetRemove this label when the necessary documentation for the feature / change is addedRemove this label when the necessary documentation for the feature / change is added[STAGE-3] missing 2 reviews for RFC PRsRemove this label when at least 2 core team members reviewed and approved the RFC implementationRemove this label when at least 2 core team members reviewed and approved the RFC implementation
Metadata
Metadata
Assignees
Labels
[STAGE-2] incomplete implementationRemove this label when implementation is completeRemove this label when implementation is complete[STAGE-2] not fully covered by tests yetRemove this label when tests are verified to cover the implementationRemove this label when tests are verified to cover the implementation[STAGE-2] unresolved discussions leftRemove this label when all critical discussions are resolved on the issueRemove this label when all critical discussions are resolved on the issue[STAGE-3] docs changes not added yetRemove this label when the necessary documentation for the feature / change is addedRemove this label when the necessary documentation for the feature / change is added[STAGE-3] missing 2 reviews for RFC PRsRemove this label when at least 2 core team members reviewed and approved the RFC implementationRemove this label when at least 2 core team members reviewed and approved the RFC implementation
Type
Projects
Status
In Progress (STAGE 2)
Champion
@wmertens
What's the motivation for this proposal?
Problems you are trying to solve:
Goals you are trying to achieve:
Proposed Solution / Feature
What do you propose?
Right now the SSR blocks when it needs to render Promise or while a generator is running.
Instead of having a single writer connected to the response, have a stack of writers attached to the current writer, and buffer the writes.
E.g. we start with writer0 which is connected to the response object. We run
<Root/>and get<html><head/><body><App /></body></html>We can already stream
"<html><head/><body>"Next we run
<App />and get<header/><main>{contentPromise}</main><Footer />We can stream
"<header/><main>"but we have to await contentPromise before we can continue streaming.At this point, we start a new writer which buffers to memory, push it on
writer0.next[], write"</main>"to it and run<Footer />.If
contentPromiseturns out to have more promises inside, those will create more writers that are pushed on writer0.next[]`.When writer0 has nothing left to write, it recursively pop()s its
.next[], flushing it to the response.This does mean that we have to pass the writer while handling JSX, we can't use container.writer.
SSRStreamBlock
Sometimes, we need to be sure that everything above the current component has been streamed, because we're gathering data. In that case, we should output
<SSRStreamBlock />, which will block the current writer until it's the one streaming to the response.Conclusion
Using this method, we can ensure that we discover blocking Promises as early as possible, reducing the time needed to SSR the page.
Right now, Promises are serially discovered and run, and with this technique they'll all be parallel, except for waterfalls where Promises return nested Promises.
As for Out-of-Order-Streaming, using this technique will already allow waiting for like 50ms before outputting an OoOS placeholder, without actually delaying the SSR.
PRs/ Links / References
No response