Skip to content

Commit d8b1832

Browse files
author
Rich Harris
committed
add preloading exercise
1 parent 63b0509 commit d8b1832

File tree

10 files changed

+125
-0
lines changed

10 files changed

+125
-0
lines changed
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
---
2+
title: Preloading
3+
---
4+
5+
In this exercise, the `/slow-a` and `/slow-b` routes both have artificial delays in their `load` functions, meaning it takes a long time to navigate to them.
6+
7+
You can't always make your data load more quickly — sometimes it's out of your control — but SvelteKit can speed up navigations by _anticipating_ them. When an `<a>` element has a `data-sveltekit-preload-data` attribute, SvelteKit will begin the navigation as soon as the user hovers over the link (on desktop) or taps it (on mobile). Try adding it to the first link:
8+
9+
```svelte
10+
/// file: src/routes/+layout.svelte
11+
<nav>
12+
<a href="/">home</a>
13+
<a href="/slow-a" +++data-sveltekit-preload-data+++>slow-a</a>
14+
<a href="/slow-b">slow-b</a>
15+
</nav>
16+
```
17+
18+
Navigating to `/slow-a` will now be noticeably faster. Starting navigation on hover or tap (rather than waiting for a `click` event to be registered) might not sound like it makes much difference, but in practice it typically saves 200ms or more. That's enough to be the difference between sluggish and snappy.
19+
20+
You can put the attribute on individual links, or on any element that _contains_ links. The default project template includes the attribute on the `<body>` element:
21+
22+
```html
23+
/// no-file
24+
<body data-sveltekit-preload-data>
25+
%sveltekit.body%
26+
</body>
27+
```
28+
29+
You can customise the behaviour further by specifying one of the following values for the attribute:
30+
31+
- `"hover"` (default, falls back to `"tap"` on mobile)
32+
- `"tap"` — only begin preloading on tap
33+
- `"off"` — disable preloading
34+
35+
Using `data-sveltekit-preload-data` may sometimes result in false positives - i.e. loading data in anticipation of a navigation that doesn't then happen — which might be undesirable. As an alternative, `data-sveltekit-preload-code` allows you to preload the JavaScript needed by a given route without eagerly loading its data. This attribute can have the following values:
36+
37+
- `"eager"` — preload everything on the page following a navigation
38+
- `"viewport"` — preload everything as it appears in the viewport
39+
- `"hover"` (default) as above
40+
- `"tap"` — as above
41+
- `"off"` — as above
42+
43+
You can also initiate preloading programmatically with `preloadCode` and `preloadData` imported from `$app/navigation`:
44+
45+
```js
46+
/// no-file
47+
import { preloadCode, preloadData } from '$app/navigation';
48+
49+
// preload the code and data needed to navigate to /foo
50+
preloadData('/foo');
51+
52+
// preload the code needed to navigate to /bar, but not the data
53+
preloadCode('/bar');
54+
```
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<script>
2+
import { navigating } from '$app/stores';
3+
4+
let previous;
5+
let start;
6+
let end;
7+
8+
$: if ($navigating) {
9+
start = Date.now();
10+
end = null;
11+
previous = $navigating;
12+
} else {
13+
end = Date.now();
14+
}
15+
</script>
16+
17+
<nav>
18+
<a href="/">home</a>
19+
<a href="/slow-a">slow-a</a>
20+
<a href="/slow-b">slow-b</a>
21+
</nav>
22+
23+
<slot />
24+
25+
{#if previous && end}
26+
<p>navigated from {previous.from.url.pathname} to {previous.to.url.pathname} in <strong>{end - start}ms</strong></p>
27+
{/if}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<h1>home</h1>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export async function load() {
2+
await new Promise((fulfil) => {
3+
setTimeout(fulfil, 1000);
4+
});
5+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<h1>slow (a)</h1>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export async function load() {
2+
await new Promise((fulfil) => {
3+
setTimeout(fulfil, 1000);
4+
});
5+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<h1>slow (b)</h1>
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<script>
2+
import { navigating } from '$app/stores';
3+
4+
let previous;
5+
let start;
6+
let end;
7+
8+
$: if ($navigating) {
9+
start = Date.now();
10+
end = null;
11+
previous = $navigating;
12+
} else {
13+
end = Date.now();
14+
}
15+
</script>
16+
17+
<nav>
18+
<a href="/">home</a>
19+
<a href="/slow-a" data-sveltekit-preload-data>slow-a</a>
20+
<a href="/slow-b">slow-b</a>
21+
</nav>
22+
23+
<slot />
24+
25+
{#if previous && end}
26+
<p>navigated from {previous.from.url.pathname} to {previous.to.url.pathname} in <strong>{end - start}ms</strong></p>
27+
{/if}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"title": "Link options"
3+
}

src/routes/tutorial/[slug]/Output.svelte

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@
167167
transform: translate(0, 100%);
168168
transition: transform 0.3s;
169169
backdrop-filter: blur(3px);
170+
overflow-y: auto;
170171
}
171172
172173
.terminal::after {

0 commit comments

Comments
 (0)