UNPKG

opencode-agent-kit

Version:

Multi-stack OpenCode agent toolkit — 33+ specialized AI agents, 200+ skills, 46 commands, 8 MCP servers (Nuxt, React, Node.js, Laravel, CI3, Android, Flutter, DevOps, SEO, SonarQube, and more)

100 lines (80 loc) 2.51 kB
--- title: Strategic Suspense Boundaries impact: HIGH impactDescription: faster initial paint tags: async, suspense, streaming, layout-shift --- ## Strategic Suspense Boundaries Instead of awaiting data in async components before returning JSX, use Suspense boundaries to show the wrapper UI faster while data loads. **Incorrect (wrapper blocked by data fetching):** ```tsx async function Page() { const data = await fetchData() // Blocks entire page return ( <div> <div>Sidebar</div> <div>Header</div> <div> <DataDisplay data={data} /> </div> <div>Footer</div> </div> ) } ``` The entire layout waits for data even though only the middle section needs it. **Correct (wrapper shows immediately, data streams in):** ```tsx function Page() { return ( <div> <div>Sidebar</div> <div>Header</div> <div> <Suspense fallback={<Skeleton />}> <DataDisplay /> </Suspense> </div> <div>Footer</div> </div> ) } async function DataDisplay() { const data = await fetchData() // Only blocks this component return <div>{data.content}</div> } ``` Sidebar, Header, and Footer render immediately. Only DataDisplay waits for data. **Alternative (share promise across components):** ```tsx function Page() { // Start fetch immediately, but don't await const dataPromise = fetchData() return ( <div> <div>Sidebar</div> <div>Header</div> <Suspense fallback={<Skeleton />}> <DataDisplay dataPromise={dataPromise} /> <DataSummary dataPromise={dataPromise} /> </Suspense> <div>Footer</div> </div> ) } function DataDisplay({ dataPromise }: { dataPromise: Promise<Data> }) { const data = use(dataPromise) // Unwraps the promise return <div>{data.content}</div> } function DataSummary({ dataPromise }: { dataPromise: Promise<Data> }) { const data = use(dataPromise) // Reuses the same promise return <div>{data.summary}</div> } ``` Both components share the same promise, so only one fetch occurs. Layout renders immediately while both components wait together. **When NOT to use this pattern:** - Critical data needed for layout decisions (affects positioning) - SEO-critical content above the fold - Small, fast queries where suspense overhead isn't worth it - When you want to avoid layout shift (loading → content jump) **Trade-off:** Faster initial paint vs potential layout shift. Choose based on your UX priorities.