Skip to content

Commit

Permalink
Replace data-sveltekit-prefetch/prefetch(...)/`prefetchRoutes(...…
Browse files Browse the repository at this point in the history
…)` (#7776)

* rename prefetch -> preload and prefetchRoutes -> prepare, tweak prepare API

* rename data-sveltekit-prefetch to data-sveltekit-preload

* update migration guide

* various

* shuffle some things around

* refactor a tiny bit

* fix

* implement data-sveltekit-prepare

* make it slightly more self-contained

* keyboard events

* named constants

* handle malformed URLs

* rename

* use data-sveltekit-preload-code and data-sveltekit-preload-data

* rename stuff

* fix

* docs

* missed a spot

* changesets

* clarification

* fix migration guide

* tidy up

* feat: Typing improvements to preload PR (#7841)

* feat: Improve typings on data-sveltekit attributes

* feat: improved constants

* Update packages/kit/src/runtime/client/utils.js

Co-authored-by: gtmnayan <50981692+gtm-nayan@users.noreply.github.com>

* remove dev guard from validateAttributeValue

* snake_case

* dot notation

* shorter name so prettier doesnt butcher the code

* shorter name

* get typechecking working

* neaten

* oops

* tweak

Co-authored-by: Rich Harris <richard.a.harris@gmail.com>
Co-authored-by: gtmnayan <50981692+gtm-nayan@users.noreply.github.com>
Co-authored-by: Rich Harris <hello@rich-harris.dev>

* Update documentation/docs/30-advanced/30-link-options.md

* move up explanation of mobile behaviour

* clarify

* Update packages/kit/src/runtime/client/client.js

Co-authored-by: S. Elliott Johnson <sejohnson@torchcloudconsulting.com>

* change "page" to "eager"

* make side-effecty

* oops

* fix docs

Co-authored-by: S. Elliott Johnson <sejohnson@torchcloudconsulting.com>
Co-authored-by: gtmnayan <50981692+gtm-nayan@users.noreply.github.com>
  • Loading branch information
3 people authored Nov 28, 2022
1 parent 191583c commit 02ba6a6
Show file tree
Hide file tree
Showing 38 changed files with 384 additions and 209 deletions.
6 changes: 6 additions & 0 deletions .changeset/cold-shoes-cheat.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@sveltejs/kit': patch
'create-svelte': patch
---

[breaking] Replace `data-sveltekit-prefetch` with `-preload-code` and `-preload-data`
5 changes: 5 additions & 0 deletions .changeset/many-schools-live.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@sveltejs/kit': patch
---

[breaking] Rename `prefetch` to `preloadData` and `prefetchRoutes` to `preloadCode`
2 changes: 1 addition & 1 deletion documentation/docs/10-getting-started/10-introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ title: Introduction

SvelteKit is a framework for building extremely high-performance web apps.

Building an app with all the modern best practices is fiendishly complicated. Those practices include [build optimizations](https://vitejs.dev/guide/features.html#build-optimizations), so that you load only the minimal required code; [offline support](/docs/service-workers); [prefetching](/docs/link-options#data-sveltekit-prefetch) pages before the user initiates navigation; and [configurable rendering](/docs/page-options) that allows you to render your app [on the server](/docs/glossary#ssr) or [in the browser](/docs/glossary#csr-and-spa) at runtime or [at build-time](/docs/glossary#prerendering). SvelteKit does all the boring stuff for you so that you can get on with the creative part.
Building an app with all the modern best practices is fiendishly complicated. Those practices include [build optimizations](https://vitejs.dev/guide/features.html#build-optimizations), so that you load only the minimal required code; [offline support](/docs/service-workers); [preloading](/docs/link-options#data-sveltekit-preload-data) pages before the user initiates navigation; and [configurable rendering](/docs/page-options) that allows you to render your app [on the server](/docs/glossary#ssr) or [in the browser](/docs/glossary#csr-and-spa) at runtime or [at build-time](/docs/glossary#prerendering). SvelteKit does all the boring stuff for you so that you can get on with the creative part.

It uses [Vite](https://vitejs.dev/) with a [Svelte plugin](https://github.com/sveltejs/vite-plugin-svelte) to provide a lightning-fast and feature-rich development experience with [Hot Module Replacement (HMR)](https://github.com/sveltejs/vite-plugin-svelte/blob/main/docs/config.md#hot), where changes to your code are reflected in the browser instantly.

Expand Down
57 changes: 45 additions & 12 deletions documentation/docs/30-advanced/30-link-options.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,53 @@ In SvelteKit, `<a>` elements (rather than framework-specific `<Link>` components

You can customise the behaviour of links with `data-sveltekit-*` attributes. These can be applied to the `<a>` itself, or to a parent element.

### data-sveltekit-prefetch
### data-sveltekit-preload-data

To get a head start on importing the code and fetching the page's data, use the `data-sveltekit-prefetch` attribute, which will start loading everything as soon as the user hovers over the link (on a desktop) or touches it (on mobile), rather than waiting for the `click` event to trigger navigation. Typically, this buys us an extra couple of hundred milliseconds, which is the difference between a user interface that feels laggy, and one that feels snappy.
Before the browser registers that the user has clicked on a link, we can detect that they've hovered the mouse over it (on desktop) or that a `touchstart` or `mousedown` event was triggered. In both cases, we can make an educated guess that a `click` event is coming.

To apply this behaviour across the board, add the attribute to a parent element (or even the `<body>` in your `src/app.html`):
SvelteKit can use this information to get a head start on importing the code and fetching the page's data, which can give us an extra couple of hundred milliseconds — the difference between a user interface that feels laggy and one that feels snappy.

We can control this behaviour with the `data-sveltekit-preload-data` attribute, which can have one of two values:

- `"hover"` means that preloading will start if the mouse comes to a rest over a link. On mobile, preloading begins on `touchstart`
- `"tap"` means that preloading will start as soon as a `touchstart` or `mousedown` event is registered

The default project template has a `data-sveltekit-preload-data="hover"` attribute applied to the `<body>` element in `src/app.html`, meaning that every link is preloaded on hover by default:

```html
<body data-sveltekit-preload-data="hover">
<div style="display: contents">%sveltekit.body%</div>
</body>
```

Sometimes, calling `load` when the user hovers over a link might be undesirable, either because it's likely to result in false positives (a click needn't follow a hover) or because data is updating very quickly and a delay could mean staleness.

In these cases, you can specify the `"tap"` value, which causes SvelteKit to call `load` only when the user taps or clicks on a link:

```html
/// file: src/routes/+layout.svelte
<main data-sveltekit-prefetch>
<slot />
</main>
<a data-sveltekit-preload-data="tap" href="/stonks">
Get current stonk values
</a>
```

> You can also programmatically invoke `prefetch` from `$app/navigation`.
> You can also programmatically invoke `preloadData` from `$app/navigation`.
Data will never be preloaded if the user has chosen reduced data usage, meaning [`navigator.connection.saveData`](https://developer.mozilla.org/en-US/docs/Web/API/NetworkInformation/saveData) is `true`.

### data-sveltekit-preload-code

Even in cases where you don't want to preload _data_ for a link, it can be beneficial to preload the _code_. The `data-sveltekit-preload-code` attribute works similarly to `data-sveltekit-preload-data`, except that it can take one of four values, in decreasing 'eagerness':

- `"eager"` means that links will be preloaded straight away
- `"viewport"` means that links will be preloaded once they enter the viewport
- `"hover"` - as above, except that only code is preloaded
- `"tap"` - as above, except that only code is preloaded

Note that `viewport` and `eager` only apply to links that are present in the DOM immediately following navigation — if a link is added later (in an `{#if ...}` block, for example) it will not be preloaded until triggered by `hover` or `tap`. This is to avoid performance pitfalls resulting from aggressively observing the DOM for changes.

> Since preloading code is a prerequisite for preloading data, this attribute will only have an effect if it specifies a more eager value than any `data-sveltekit-preload-data` attribute that is present.
As with `data-sveltekit-preload-data`, this attribute will be ignored if the user has chosen reduced data usage.

### data-sveltekit-reload

Expand Down Expand Up @@ -50,14 +83,14 @@ In certain cases, you may wish to disable this behaviour. Adding a `data-sveltek
To disable any of these options inside an element where they have been enabled, use the `"off"` value:

```html
<div data-sveltekit-prefetch>
<!-- these links will be prefetched -->
<div data-sveltekit-preload-data>
<!-- these links will be preloaded -->
<a href="/a">a</a>
<a href="/b">b</a>
<a href="/c">c</a>

<div data-sveltekit-prefetch="off">
<!-- these links will NOT be prefetched -->
<div data-sveltekit-preload-data="off">
<!-- these links will NOT be preloaded -->
<a href="/d">d</a>
<a href="/e">e</a>
<a href="/f">f</a>
Expand Down
4 changes: 2 additions & 2 deletions documentation/docs/60-appendix/10-migrating.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ Your custom error page component should be renamed from `_error.svelte` to `+err

#### Imports

The `goto`, `prefetch` and `prefetchRoutes` imports from `@sapper/app` should be replaced with identical imports from [`$app/navigation`](/docs/modules#$app-navigation).
The `goto`, `prefetch` and `prefetchRoutes` imports from `@sapper/app` should be replaced with `goto`, `preloadData` and `preloadCode` imports respectively from [`$app/navigation`](/docs/modules#$app-navigation).

The `stores` import from `@sapper/app` should be replaced — see the [Stores](/docs/migrating#pages-and-layouts-stores) section below.

Expand Down Expand Up @@ -133,7 +133,7 @@ This caused problems and is no longer the case in SvelteKit. Instead, relative U

#### &lt;a&gt; attributes

- `sapper:prefetch` is now `data-sveltekit-prefetch`
- `sapper:prefetch` is now `data-sveltekit-preload-data`
- `sapper:noscroll` is now `data-sveltekit-noscroll`

### Endpoints
Expand Down
2 changes: 1 addition & 1 deletion packages/create-svelte/templates/default/src/app.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<meta name="viewport" content="width=device-width" />
%sveltekit.head%
</head>
<body data-sveltekit-prefetch>
<body data-sveltekit-preload-data="hover">
<div style="display: contents">%sveltekit.body%</div>
</body>
</html>
2 changes: 1 addition & 1 deletion packages/create-svelte/templates/skeleton/src/app.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<meta name="viewport" content="width=device-width" />
%sveltekit.head%
</head>
<body>
<body data-sveltekit-preload-data="hover">
<div style="display: contents">%sveltekit.body%</div>
</body>
</html>
4 changes: 2 additions & 2 deletions packages/kit/src/runtime/app/navigation.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export const disableScrollHandling = ssr
export const goto = ssr ? guard('goto') : client.goto;
export const invalidate = ssr ? guard('invalidate') : client.invalidate;
export const invalidateAll = ssr ? guard('invalidateAll') : client.invalidateAll;
export const prefetch = ssr ? guard('prefetch') : client.prefetch;
export const prefetchRoutes = ssr ? guard('prefetchRoutes') : client.prefetch_routes;
export const preloadData = ssr ? guard('preloadData') : client.preload_data;
export const preloadCode = ssr ? guard('preloadCode') : client.preload_code;
export const beforeNavigate = ssr ? () => {} : client.before_navigate;
export const afterNavigate = ssr ? () => {} : client.after_navigate;
Loading

0 comments on commit 02ba6a6

Please sign in to comment.