---
id: request-waterfalls
title: Performance & Request Waterfalls
ref: docs/framework/react/guides/request-waterfalls.md
replace: { 'React Query': 'Solid Query' }
---
[//]: # 'AdvancedSSRLink'
[//]: # 'AdvancedSSRLink'
[//]: # 'DependentExample'
```tsx
// Get the user
const userQuery = useQuery(() => ({
queryKey: ['user', email],
queryFn: getUserByEmail,
}))
const userId = () => userQuery.data?.id
// Then get the user's projects
const projectsQuery = useQuery(() => ({
queryKey: ['projects', userId()],
queryFn: getProjectsByUser,
// The query will not execute until the userId exists
enabled: !!userId(),
}))
```
[//]: # 'DependentExample'
[//]: # 'ServerComponentsNote1'
[//]: # 'ServerComponentsNote1'
[//]: # 'SuspenseSerial'
[//]: # 'SuspenseSerial'
[//]: # 'NestedIntro'
Nested Component Waterfalls is when both a parent and a child component contains queries, and the parent does not render the child until its query is done.
[//]: # 'NestedIntro'
[//]: # 'NestedExample'
```tsx
import { Switch, Match } from 'solid-js'
function Article(props) {
const articleQuery = useQuery(() => ({
queryKey: ['article', props.id],
queryFn: getArticleById,
}))
return (
Loading article...
)
}
function Comments(props) {
const commentsQuery = useQuery(() => ({
queryKey: ['article-comments', props.id],
queryFn: getArticleCommentsById,
}))
...
}
```
[//]: # 'NestedExample'
[//]: # 'NestedHoistedExample'
```tsx
import { Switch, Match, Show } from 'solid-js'
function Article(props) {
const articleQuery = useQuery(() => ({
queryKey: ['article', props.id],
queryFn: getArticleById,
}))
const commentsQuery = useQuery(() => ({
queryKey: ['article-comments', props.id],
queryFn: getArticleCommentsById,
}))
return (
Loading article...
Loading comments...
)
}
```
[//]: # 'NestedHoistedExample'
[//]: # 'NestedHoistedOutro'
The two queries will now fetch in parallel.
[//]: # 'NestedHoistedOutro'
[//]: # 'DependentNestedExample'
```tsx
import { Switch, Match, For } from 'solid-js'
function Feed() {
const feedQuery = useQuery(() => ({
queryKey: ['feed'],
queryFn: getFeed,
}))
return (
Loading feed...
{(feedItem) => {
if (feedItem.type === 'GRAPH') {
return
}
return
}}
)
}
function GraphFeedItem(props) {
const graphQuery = useQuery(() => ({
queryKey: ['graph', props.feedItem.id],
queryFn: getGraphDataById,
}))
...
}
```
[//]: # 'DependentNestedExample'
[//]: # 'ServerComponentsNote2'
In this example, we can't trivially flatten the waterfall by just hoisting the query to the parent, or even adding prefetching. Just like the dependent query example at the beginning of this guide, one option is to refactor our API to include the graph data in the `getFeed` query.
[//]: # 'ServerComponentsNote2'
[//]: # 'LazyExample'
```tsx
import { lazy, Switch, Match, For } from 'solid-js'
// This lazy loads the GraphFeedItem component, meaning
// it wont start loading until something renders it
const GraphFeedItem = lazy(() => import('./GraphFeedItem'))
function Feed() {
const feedQuery = useQuery(() => ({
queryKey: ['feed'],
queryFn: getFeed,
}))
return (
Loading feed...
{(feedItem) => {
if (feedItem.type === 'GRAPH') {
return
}
return
}}
)
}
// GraphFeedItem.tsx
function GraphFeedItem(props) {
const graphQuery = useQuery(() => ({
queryKey: ['graph', props.feedItem.id],
queryFn: getGraphDataById,
}))
...
}
```
[//]: # 'LazyExample'
[//]: # 'ServerComponentsNote3'
[//]: # 'ServerComponentsNote3'