SvelteKitのパフォーマンス最適化(preloadData・preloadCode・goto)を整理した話
SvelteKitのリンク先読み機能(preload)を整理します。リンクにカーソルを乗せた瞬間にデータを先読みして、ページ遷移を体感的に速くします。
① data-sveltekit-preload-data — データの先読み
リンクにカーソルが乗ったタイミングで load 関数を先に実行します。クリックまでの数百ミリ秒の間にデータを取得するため、クリック時にはすでにデータが準備できています。
<a href="/posts/1" data-sveltekit-preload-data="hover">記事を見る</a>
指定できる値:
| 値 | タイミング |
|---|---|
hover |
カーソルが乗ったとき(デスクトップ向け) |
tap |
タップ開始時(モバイル向け) |
off |
先読みしない |
② +layout.svelte に一括設定する
全リンクに個別に書くのは大変なので、レイアウトに一括設定するのが一般的です。
<!-- src/routes/+layout.svelte -->
<main>
<div data-sveltekit-preload-data="hover">
{@render children()}
</div>
</main>
この div の内側にあるリンクはすべてhoverで先読みされます。
③ data-sveltekit-preload-code — コードの先読み
データではなくJavaScriptのコード(ページコンポーネント)を先読みします。
<a href="/posts/1" data-sveltekit-preload-code="hover">記事を見る</a>
preload-data と preload-code の違い:
preload-code → ページのJSファイルだけ先読み(load関数は実行しない)
preload-data → load関数も実行してデータまで先読み(より積極的)
DBアクセスを伴う load 関数を気軽に先読みしたくない場合は preload-code が安全です。
④ goto でプログラムから遷移する
ボタンクリックなどでページ遷移するときは goto を使います。
<script lang="ts">
import { goto } from '$app/navigation';
async function handleSubmit() {
await fetch('/api/posts', { method: 'POST' });
goto('/posts'); // /posts に遷移
}
</script>
goto のオプション:
goto('/posts', {
replaceState: true, // 履歴を置き換える(戻れなくなる)
invalidateAll: true, // 遷移先のloadを再実行する
});
動作確認の方法
preload-data が動いているとサーバーログに __data.json へのリクエストが記録されます。
GET /posts/1/__data.json 200 12ms
SvelteKitのpreloadはページ遷移時にHTMLページを返すのではなく、__data.json という形式でデータだけを取得します。
ブラウザのNetwork タブで確認するには:
- Preserve log にチェックを入れる
- フィルターを Fetch/XHR に絞る
- その状態でリンクにホバーする
サーバーログに __data.json リクエストが記録されていれば正しく動いています。
まとめ
| 機能 | 効果 | 設定場所 |
|---|---|---|
preload-data="hover" |
load関数まで先読み | リンクまたはレイアウト |
preload-code="hover" |
JSだけ先読み | リンクまたはレイアウト |
goto() |
プログラムからページ遷移 | イベントハンドラ内 |
+layout.svelte に data-sveltekit-preload-data="hover" を追加するだけでページ遷移が体感的に速くなります。