-
-
Notifications
You must be signed in to change notification settings - Fork 3.7k
docs(solid-query): convert guide docs to ref-based with Solid-style code #10146
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
98404f2
bc62e86
f886568
786cd36
cd3b683
56d5c2b
9bfc61e
ec4bb38
77a6218
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,8 +11,12 @@ The [Prefetching & Router Integration guide](./prefetching.md) builds on this an | |
|
|
||
| The [Server Rendering & Hydration guide](./ssr.md) teaches you how to prefetch data on the server and pass that data down to the client so you don't have to fetch it again. | ||
|
|
||
| [//]: # 'AdvancedSSRLink' | ||
|
|
||
| The [Advanced Server Rendering guide](./advanced-ssr.md) further teaches you how to apply these patterns to Server Components and Streaming Server Rendering. | ||
|
|
||
| [//]: # 'AdvancedSSRLink' | ||
|
|
||
| ## What is a Request Waterfall? | ||
|
|
||
| A request waterfall is what happens when a request for a resource (code, css, images, data) does not start until _after_ another request for a resource has finished. | ||
|
|
@@ -67,6 +71,8 @@ With this as a basis, let's look at a few different patterns that can lead to Re | |
|
|
||
| When a single component first fetches one query, and then another, that's a request waterfall. This can happen when the second query is a [Dependent Query](./dependent-queries.md), that is, it depends on data from the first query when fetching: | ||
|
|
||
| [//]: # 'DependentExample' | ||
|
|
||
| ```tsx | ||
| // Get the user | ||
| const { data: user } = useQuery({ | ||
|
|
@@ -89,10 +95,17 @@ const { | |
| }) | ||
| ``` | ||
|
|
||
| [//]: # 'DependentExample' | ||
|
|
||
| While not always feasible, for optimal performance it's better to restructure your API so you can fetch both of these in a single query. In the example above, instead of first fetching `getUserByEmail` to be able to `getProjectsByUser`, introducing a new `getProjectsByUserEmail` query would flatten the waterfall. | ||
|
|
||
| [//]: # 'ServerComponentsNote1' | ||
|
|
||
| > Another way to mitigate dependent queries without restructuring your API is to move the waterfall to the server where latency is lower. This is the idea behind Server Components which are covered in the [Advanced Server Rendering guide](./advanced-ssr.md). | ||
|
|
||
| [//]: # 'ServerComponentsNote1' | ||
| [//]: # 'SuspenseSerial' | ||
|
|
||
| Another example of serial queries is when you use React Query with Suspense: | ||
|
|
||
| ```tsx | ||
|
|
@@ -122,14 +135,22 @@ const [usersQuery, teamsQuery, projectsQuery] = useSuspenseQueries({ | |
| }) | ||
| ``` | ||
|
|
||
| [//]: # 'SuspenseSerial' | ||
|
|
||
| ### Nested Component Waterfalls | ||
|
|
||
| [//]: # '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. This can happen both with `useQuery` and `useSuspenseQuery`. | ||
|
|
||
| [//]: # 'NestedIntro' | ||
|
|
||
| If the child renders conditionally based on the data in the parent, or if the child relies on some part of the result being passed down as a prop from the parent to make its query, we have a _dependent_ nested component waterfall. | ||
|
|
||
| Let's first look at an example where the child is **not** dependent on the parent. | ||
|
|
||
| [//]: # 'NestedExample' | ||
|
|
||
| ```tsx | ||
| function Article({ id }) { | ||
| const { data: articleData, isPending } = useQuery({ | ||
|
|
@@ -161,8 +182,12 @@ function Comments({ id }) { | |
| } | ||
| ``` | ||
|
|
||
| [//]: # 'NestedExample' | ||
|
|
||
| Note that while `<Comments>` takes a prop `id` from the parent, that id is already available when the `<Article>` renders so there is no reason we could not fetch the comments at the same time as the article. In real world applications, the child might be nested far below the parent and these kinds of waterfalls are often trickier to spot and fix, but for our example, one way to flatten the waterfall would be to hoist the comments query to the parent instead: | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hyphenate compound modifiers for grammar consistency. These read as compound adjectives and should be hyphenated. ✍️ Suggested edits- In real world applications, the child might be nested far below the parent
+ In real-world applications, the child might be nested far below the parent
- - Include all data fetching code in the main bundle, even if we seldom use it
- - Put the data fetching code in the code split bundle, but with a request waterfall
+ - Include all data-fetching code in the main bundle, even if we seldom use it
+ - Put the data-fetching code in the code-split bundle, but with a request-waterfallAlso applies to: 368-369 🧰 Tools🪛 LanguageTool[grammar] ~187-~187: Use a hyphen to join words. (QB_NEW_EN_HYPHEN) 🤖 Prompt for AI Agents |
||
|
|
||
| [//]: # 'NestedHoistedExample' | ||
|
|
||
| ```tsx | ||
| function Article({ id }) { | ||
| const { data: articleData, isPending: articlePending } = useQuery({ | ||
|
|
@@ -193,12 +218,19 @@ function Article({ id }) { | |
| } | ||
| ``` | ||
|
|
||
| [//]: # 'NestedHoistedExample' | ||
| [//]: # 'NestedHoistedOutro' | ||
|
|
||
| The two queries will now fetch in parallel. Note that if you are using suspense, you'd want to combine these two queries into a single `useSuspenseQueries` instead. | ||
|
|
||
| [//]: # 'NestedHoistedOutro' | ||
|
|
||
| Another way to flatten this waterfall would be to prefetch the comments in the `<Article>` component, or prefetch both of these queries at the router level on page load or page navigation, read more about this in the [Prefetching & Router Integration guide](./prefetching.md). | ||
|
|
||
| Next, let's look at a _Dependent Nested Component Waterfall_. | ||
|
|
||
| [//]: # 'DependentNestedExample' | ||
|
|
||
| ```tsx | ||
| function Feed() { | ||
| const { data, isPending } = useQuery({ | ||
|
|
@@ -233,15 +265,21 @@ function GraphFeedItem({ feedItem }) { | |
| } | ||
| ``` | ||
|
|
||
| [//]: # 'DependentNestedExample' | ||
|
|
||
| The second query `getGraphDataById` is dependent on its parent in two different ways. First of all, it doesn't ever happen unless the `feedItem` is a graph, and second, it needs an `id` from the parent. | ||
|
|
||
| ``` | ||
| 1. |> getFeed() | ||
| 2. |> getGraphDataById() | ||
| ``` | ||
|
Comment on lines
272
to
275
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add a language to the fenced code block. Markdownlint warns about missing language specifier here. Consider marking it as plain text. 💡 Suggested change-```
+```text
1. |> getFeed()
2. |> getGraphDataById()🧰 Tools🪛 markdownlint-cli2 (0.21.0)[warning] 272-272: Fenced code blocks should have a language specified (MD040, fenced-code-language) 🤖 Prompt for AI Agents |
||
|
|
||
| [//]: # '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. Another more advanced solution is to leverage Server Components to move the waterfall to the server where latency is lower (read more about this in the [Advanced Server Rendering guide](./advanced-ssr.md)) but note that this can be a very big architectural change. | ||
|
|
||
| [//]: # 'ServerComponentsNote2' | ||
|
|
||
| You can have good performance even with a few query waterfalls here and there, just know they are a common performance concern and be mindful about them. An especially insidious version is when Code Splitting is involved, let's take a look at this next. | ||
|
|
||
| ### Code Splitting | ||
|
|
@@ -323,13 +361,17 @@ In the code split case, it might actually help to hoist the `getGraphDataById` q | |
|
|
||
| This is very much a tradeoff however. You are now including the data fetching code for `getGraphDataById` in the same bundle as `<Feed>`, so evaluate what is best for your case. Read more about how to do this in the [Prefetching & Router Integration guide](./prefetching.md). | ||
|
|
||
| [//]: # 'ServerComponentsNote3' | ||
|
|
||
| > The tradeoff between: | ||
| > | ||
| > - Include all data fetching code in the main bundle, even if we seldom use it | ||
| > - Put the data fetching code in the code split bundle, but with a request waterfall | ||
| > | ||
| > is not great and has been one of the motivations for Server Components. With Server Components, it's possible to avoid both, read more about how this applies to React Query in the [Advanced Server Rendering guide](./advanced-ssr.md). | ||
|
|
||
| [//]: # 'ServerComponentsNote3' | ||
|
|
||
| ## Summary and takeaways | ||
|
|
||
| Request Waterfalls are a very common and complex performance concern with many tradeoffs. There are many ways to accidentally introduce them into your application: | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hyphenate compound modifier in docs text.
On Line 41, “non-JSON compatible values” should be “non-JSON-compatible values” for correct grammar and consistency.
✏️ Proposed wording tweak
📝 Committable suggestion
🧰 Tools
🪛 LanguageTool
[grammar] ~41-~41: Use a hyphen to join words.
Context: ...` flag. If you are dealing with non-JSON compatible values in your query response...
(QB_NEW_EN_HYPHEN)
[style] ~41-~41: In contexts where ‘if’ is followed by ‘or’, using ‘whether’ may be more appropriate (and formal).
Context: ...uery responses and still want to detect if data has changed or not, you can provid...
(IF_WHETHER)
🤖 Prompt for AI Agents