- Notifications
You must be signed in to change notification settings - Fork 330
content: Expand notes on preloading data #1306
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
base: main
Are you sure you want to change the base?
Changes from all commits
4a50173
50d0a0c
a2ab463
f364e32
a4c79c1
7937b09
0fe3593
e640128
a46fd80
f805d73
5788b7d
3d47fe4
203df8d
b1a0fb0
4b4f2e3
143ba25
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 |
---|---|---|
| @@ -2,24 +2,75 @@ | |
title: lazy | ||
--- | ||
| ||
```ts | ||
Used to lazy load components to allow for code splitting. | ||
Components are not loaded until rendered or manually preloaded. | ||
| ||
```tsx title="app.tsx" | ||
import { lazy } from "solid-js" | ||
| ||
const ComponentA = lazy(() => import("./ComponentA")); | ||
| ||
function App(props: { title: string }) { | ||
return ( | ||
<ComponentA title={props.title} /> | ||
) | ||
} | ||
``` | ||
| ||
Lazy loaded components can be used the same as its statically imported counterpart, receiving props etc. | ||
Lazy components trigger `<Suspense>` | ||
| ||
## Preloading data in Nested Lazy Components | ||
| ||
Top-level lazy components will automatically be preloaded as well as their preload functions. | ||
However, nested lazy components will not be preloaded automatically because they are not part of the route hierarchy. | ||
To preload such components, you can use the `preload` method exposed on the lazy component. | ||
| ||
```tsx title="component-with-preload.tsx" | ||
import { lazy } from "solid-js" | ||
import type { Component } from "solid-js" | ||
| ||
const Nested = lazy(() => import("./Nested")) | ||
| ||
const ComponentWithPreload: Component = () => { | ||
// preload Nested component when needed | ||
async function handlePreload() { | ||
await Nested.preload() | ||
} | ||
| ||
return ( | ||
<div> | ||
<button onClick={handlePreload}>Preload Nested Component</button> | ||
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. By the time the button is visible and before it's able to be clicked, | ||
<Nested /> | ||
</div> | ||
) | ||
} | ||
| ||
``` | ||
| ||
## Type Signature | ||
| ||
```tsx | ||
function lazy<T extends Component<any>>( | ||
fn: () => Promise<{ default: T }> | ||
): T & { preload: () => Promise<T> } | ||
``` | ||
| ||
Used to lazy load components to allow for code splitting. | ||
Components are not loaded until rendered. | ||
Lazy loaded components can be used the same as its statically imported counterpart, receiving props etc. | ||
Lazy components trigger `<Suspense>` | ||
### Type Parameters | ||
| ||
```tsx | ||
// wrap import | ||
const ComponentA = lazy(() => import("./ComponentA")); | ||
| Name | Constraint | Description | | ||
| ---- | ---------- | ----------- | | ||
| `T` | `Component<any>` | The component type that will be lazily loaded (including its props). | ||
| ||
### Parameters | ||
| ||
| Parameter | Type | Required | Description | | ||
| --------- | ---- | -------- | ----------- | | ||
| `fn` | `() => Promise<{ default: T }>` | Yes | A function that returns a dynamic import resolving to the component as the `default` export. | | ||
| ||
### Returns | ||
| ||
| Type | Description | | ||
| ---- | ----------- | | ||
| `T & { preload: () => Promise<T> }` | A renderable component compatible with `T` that also exposes a `preload()` method to eagerly load the module. | | ||
| ||
// use in JSX | ||
<ComponentA title={props.title} /> | ||
``` |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
{ | ||
"title": "Advanced concepts", | ||
"pages": ["lazy-loading.mdx"] | ||
"pages": ["preloading.mdx", "lazy-loading.mdx"] | ||
} |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,24 @@ | ||||||
--- | ||||||
title: Preloading | ||||||
--- | ||||||
| ||||||
Anchors in Solid Router will preload routes by default on link hover/focus to improve perceived performance. | ||||||
| ||||||
To enhance preloading, you can define the `preload` function on your route definition. | ||||||
When on a [SolidStart](/solid-start) application, this function can also run on the server during the initial page load to start fetching data before rendering. When in a Single-Page Application (SPA), it will load the route's component and its `preload` function when the user hovers or focuses on a link. | ||||||
| ||||||
| user action | route behavior | | ||||||
| ----------- | -------------------------------------- | | ||||||
| hover | with a 300ms delay to avoid excessive preloading | | ||||||
atilafassina marked this conversation as resolved. Show resolved Hide resolved | ||||||
| focus | immediately | | ||||||
Comment on lines +8 to +13 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. I think the SolidStart section might be more appropriate in the reference section as a callout so it doesn't get buried here. Following that change, I also believe it might be better to show a basic code snippet of what the hover would look like. Doesn't have to be too complex, just enough to get the idea across for how it should look. 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. the code snippet is in the respective API references. This entry is to explain conceptually how preloading works in Solid Router. I added links to the the APIs so things didn't get too repetitive Not sure what you mean about the hover snippet, that's just the browser API, there's no code from the user to manage or handle that. If they hover or focus the anchor tag, preloading will happen. Remember: preloading is default behavior. Altering it is an advanced concept for users, most cases we want people to feel it "just works". 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. I think as it stands for me it feels more like an extension of the ref page vs an exposure to the concept as a whole. What I meant by the hover example was that it might make it feel less like a ref page if there is some form of an example on the page of what it'd look like to modify it. My explanation wasn't entirely great (I'm sorry about that) but I'll try to give you a bit more of an idea as to what I mean tomorrow (unless @devagrawal09 has any ideas before then). 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.
The hover in this case is the regular browser hover, there's nothing framework specific on this. Regular mouse hovering a link will fire a 300ms timeout that will preload data once fulfilled. Extending on this right here feels to me like documenting browser APIs or framework implementation details. | ||||||
| ||||||
## Imperative Preloading | ||||||
| ||||||
You can also use the [`usePreloadRoute`](/solid-router/reference/primitives/use-preload-route) helper to preload routes programmatically in response to events other than link hover/focus, such as button clicks or timers. | ||||||
This helper will load only the route's component by default, but it can receive a configuration object to also load the data. | ||||||
| ||||||
## Preloading and Lazy Loading | ||||||
| ||||||
When a route has nested lazy components, such components will not be part of the route hierarchy, so they **will not** be preloaded with the route. To preload such components, you can use the [`usePreloadRoute`](/solid-router/reference/primitives/use-preload-route) helper in the parent component to load them when needed. | ||||||
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. Given the context of this paragraph, the second sentence here seems misplaced and was the problem we were initially discussing on Discord. 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. 100% 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. Cool, you seem pretty busy, so I can give it a try. Hopefully it's in the ballpark of what you had in mind. 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. Looks like the docs for the Suggested change
| ||||||
| ||||||
To learn more about lazy loading components, see the [`lazy`](/reference/component-apis/lazy#preloading-data-in-nested-lazy-components) documentation. |
Uh oh!
There was an error while loading. Please reload this page.