withastro / roadmap

Ideas, suggestions, and formal RFC proposals for the Astro project.
290 stars 29 forks source link

Allow framework components to stream responses or run in parallel #658

Closed sasoria closed 1 year ago

sasoria commented 1 year ago

What version of astro are you using?

2.6.4

Are you using an SSR adapter? If so, which one?

Node

What package manager are you using?

pnpm, npm

What operating system are you using?

Mac

What browser are you using?

Chrome

Describe the Bug

When I try to test parallel rendering of React components with promises it seems to block the entire document, until the promises resolve.

await new Promise((res) => setTimeout(res, 1800));

const ReactComponent = () => {
  return (
    <h1>{1800}ms Delayed</h1>
  );
};

export default ReactComponent;

Parallel rendring works as intended when I use Astro components. If I'm doing something wrong, please point me in the right direction.

Link to Minimal Reproducible Example

https://stackblitz.com/edit/github-wsphny?file=src%2Fpages%2Findex.astro

Participation

bluwy commented 1 year ago

Yeah we currently only support parallel rendering for Astro components, not yet for framework components. cc @johannesspohr

johannesspohr commented 1 year ago

@bluwy is right in that we don't change the render behavior of any framework, we only parallelize Astro components until we call the render functions of integrations, and what happens inside them is not affected by Astro.

However, I wonder what use-case your example is referring to? The top-level await in the component files will basically delay the evaluation of the file, not the rendering of the actual components. If you want to fetch data, you can do that in an Astro component and pass it on to the React components, or use some way to defer rendering of the React components (I'm not too much into the Astro React integration, so I can't tell anything about that).

sasoria commented 1 year ago

The use case is data fetching, however as you mentioned this could be done in Astro components that are used as wrappers for React components. Expanding further we want to load micro-frontends written in React that are Server-side rendered by Astro. To avoid coupling applications we want each micro-frontend to do its data fetching.

To sum it up the use cases are:

It has come to my attention that its possible to omit the await when fetching data. I want to explore that possibility further and I'll keep this issue updated.

johannesspohr commented 1 year ago

Looks interesting, cool approach. Maybe you could also use React Suspense to do the data fetching? As mentioned, having the data fetching at the top of your file causes that to happen outside of the render chain. (For Astro components, the whole file gets wrapped in a render function, so it will be re-evaluated on every render, but not for React files)

sasoria commented 1 year ago

Awesome! Suspense only works client-side, but I want to use it server-side once Astro has support for React server components.

natemoo-re commented 1 year ago

I'm going to move this over to our roadmap repo because it's a feature request! This would be great to support for frameworks if possible, but it could be extremely tricky. Unfortunately we need to be able to introspect the output of the framework component in order to support recursive islands, which is why we block for them currently.