-
Notifications
You must be signed in to change notification settings - Fork 331
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
738edde
4be0415
f5fdd71
c186d75
0ec7ff5
48469c4
d29d5fe
e969cad
7eec91d
f291d4d
8057066
5410b66
488749c
1406b87
b4dcd8f
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 |
|---|---|---|
|
|
@@ -16,24 +16,75 @@ description: >- | |
| performance. Components load on-demand and integrate with Suspense. | ||
| --- | ||
|
|
||
| ```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() | ||
atilafassina marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| 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,
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. Agreed, it should look something like this const ComponentWithPreload = () => {
const [showNested, setShowNested] = createSignal(false)
return (
<div>
<button
onMouseEnter={() => Nested.preload()}
onClick={() => setShowNested(true)}
>Preload Nested Component</button>
<Show when={showNested()}>
<Nested />
</Show>
</div>
)
} |
||
| <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
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. Curious where you got the 300ms from. I can only see a 20ms timeout here |
||
| | focus | immediately | | ||
|
Comment on lines
+8
to
+13
Member
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.
Member
Author
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".
Member
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).
Member
Author
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.
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. I agree with @LadyBluenotes that a more detailed explanation of what happens during SSR belongs in the solid-start docs, but it's definitely worth a callout on this page that during SSR the preload function will run before rendering, so that data fetching can be kicked off earlier. |
||
|
|
||
| ## 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 `preload()` function returned from calling the [`lazy()`](https://docs.solidjs.com/reference/component-apis/lazy) component API. | ||
|
|
||
| To learn more about lazy loading components, see the [`lazy`](/reference/component-apis/lazy#preloading-data-in-nested-lazy-components) documentation. | ||
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.
I don't think there's a concept of "top level lazy components". The only lazy components that are preloaded are route components, which means this section belongs in the router docs.
It's definitely worth calling out that lazy route components are preloaded automatically, but that callout should be further down in this page, and should link to the router docs where its explained in more detail.