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-datapreload-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 タブで確認するには:

  1. Preserve log にチェックを入れる
  2. フィルターを Fetch/XHR に絞る
  3. その状態でリンクにホバーする

サーバーログに __data.json リクエストが記録されていれば正しく動いています。


まとめ

機能 効果 設定場所
preload-data="hover" load関数まで先読み リンクまたはレイアウト
preload-code="hover" JSだけ先読み リンクまたはレイアウト
goto() プログラムからページ遷移 イベントハンドラ内

+layout.sveltedata-sveltekit-preload-data="hover" を追加するだけでページ遷移が体感的に速くなります。

← トップページに戻る