Install this skill
npx skills add vercel-labs/agent-skillsWorks across Claude Code, Cursor, Codex, Copilot & Antigravity
Strategic Suspense Boundaries focus on optimizing the perceived load time of React applications by isolating blocking data requests from the initial render. By moving heavy data fetching logic out of parent components and into specialized, suspense-wrapped children, developers prevent entire page layouts from stalling behind slow network calls. This pattern enables the immediate display of static structural elements like navbars and footers, while content-rich sections gracefully transition from loading states to fully rendered data. Beyond standard isolation, this technique supports promise sharing, where multiple components consume a single pending request to reduce redundant network overhead. Mastering this flow allows for sophisticated stream-based UI rendering, ensuring the interface remains responsive even when backend latency is significant, thereby keeping users engaged while background tasks finalize.
When to Use This Skill
- •Rendering heavy dashboard widgets that load slower than the main frame
- •Integrating multiple API calls into a single UI layout without waterfall delays
- •Decoupling static page shells from dynamic, database-driven content
- •Managing complex data dependencies across sibling components
How to Invoke This Skill
Example prompts that trigger this skill in Claude Code, Cursor, or Antigravity:
- “how to prevent page from freezing during data fetch
- “implement suspense for async component loading
- “fix render blocking in nextjs server components
- “how to stream components with react suspense
- “optimize page load speed by isolating async calls
What this skill does
- •Isolates async data dependencies from parent component trees
- •Enables incremental rendering of page sections
- •Shares singular promises across multiple dependent components
- •Reduces Time to First Meaningful Paint by bypassing blockers
- •Automates loading state transitions via fallback components
When not to use it
- ✕When content is critical for initial SEO indexing or visibility
- ✕When data determines major structural layout shifts after loading
Example workflow
- Identify components with long-running fetch operations
- Extract data-fetching logic into a separate child component
- Wrap the child component in a Suspense boundary with a skeleton fallback
- Refactor parent to render structural UI immediately
- Optional: Pass a single unresolved promise down if multiple children need identical data
Prerequisites
- –React 18+ or modern Next.js environment
- –Basic understanding of async/await patterns
- –Familiarity with Suspense and fallback UI components
Pitfalls & limitations
- !Potential for layout shift if fallback sizes differ significantly from loaded content
- !Complexity increases when managing multiple interdependent suspense boundaries
- !Overusing boundaries for trivial queries can add unnecessary runtime overhead
FAQ
How it compares
Unlike manual state management with local 'loading' booleans, this approach is declarative and integrates directly with React's core rendering pipeline, keeping components cleaner and more maintainable.
📄 Full skill instructions — original source: vercel-labs/agent-skills
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):**
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):**
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):**
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.
How to Use This Skill Unit
Option A: Project-Specific (Recommended)
- Click "Download" above
- In your project, create the directory:
.agent/skills/async-suspense-boundaries/ - Save the file as
SKILL.md - The agent will automatically discover the skill based on its description.
Option B: Global Installation (All Agents)
Save the file to these locations to make it available across all projects:
- Claude Code:
~/.claude/skills/vercel-labs/agent-skills/async-suspense-boundaries/SKILL.md - Cursor:
~/.cursor/skills/vercel-labs/agent-skills/async-suspense-boundaries/SKILL.md - Antigravity:
~/.gemini/antigravity/skills/vercel-labs/agent-skills/async-suspense-boundaries/SKILL.md
🚀 Install with CLI:npx skills add vercel-labs/agent-skills