Question presented to candidate: "There are three broad ways to combine fetching and rendering. What are they, and which would you reach for?"
What a strong answer should cover:
- fetch-on-render: the component renders, then an effect starts the request. Simple, and it creates a waterfall — a child cannot start its request until its parent's has resolved, because the child does not exist yet.
- fetch-then-render: gather everything first, render once it is all there. No waterfall, but the screen shows nothing until the slowest request lands.
- render-as-you-fetch: start the requests before or as you render, and let Suspense fill each section in as it arrives. The shell paints immediately and slow sections do not gate fast ones.
- The distinguishing question is when the request starts relative to the render — not which hook or library you use.
- Render-as-you-fetch needs the promise to be created outside render (a route loader, a cache, a Server Component), because a promise created during render never settles.
- Independent Suspense boundaries are what make sections arrive independently; one boundary around everything reintroduces "wait for the slowest".
- Frameworks implement this for you — route loaders, RSC,
preloadpatterns. Hand-rolling it in a client component is where people get it wrong.
Clarifying questions expected:
- "Are these requests independent, or does one genuinely need the other's result?" — a real dependency cannot be parallelised away.
- "Is there a router or framework that can start the fetch on navigation?"
Code / implementation expected: Optional. Showing where the promise is created is the whole distinction.