brand logo

ドキュメント

useLazyFetch

この useFetch のラッパーは、ナビゲーションを即座にトリガーします。

説明

デフォルトでは、useFetch は非同期ハンドラーが解決されるまでナビゲーションをブロックします。useLazyFetch は、lazy オプションを true に設定することで、ハンドラーが解決される前にナビゲーションをトリガーする useFetch のラッパーを提供します。

useLazyFetchuseFetch と同じシグネチャを持ちます。

このモードで useLazyFetch を待機することは、呼び出しが初期化されることのみを保証します。クライアントサイドのナビゲーションでは、データがすぐに利用可能でない場合があるため、アプリ内で保留状態を適切に処理する必要があります。

こちらも参照 api > composables > use-fetch

pages/index.vue
<script setup lang="ts">
/* フェッチが完了する前にナビゲーションが発生します。
 * コンポーネントのテンプレート内で 'pending' と 'error' の状態を直接処理します
 */
const { status, data: posts } = await useLazyFetch('/api/posts')
watch(posts, (newPosts) => {
  // posts は最初は null かもしれないので、
  // その内容にすぐにアクセスできないかもしれませんが、監視することはできます。
})
</script>

<template>
  <div v-if="status === 'pending'">
    Loading ...
  </div>
  <div v-else>
    <div v-for="post in posts">
      <!-- 何かをする -->
    </div>
  </div>
</template>

useLazyFetch はコンパイラによって変換される予約関数名であるため、自分の関数を useLazyFetch と名付けるべきではありません。

こちらも参照 getting-started > data-fetching

tips

このセクションは公式ドキュメントの翻訳ではなく、本サイト独自の補足記事です。

useLazyFetch の補足解説:ナビゲーションを妨げずにデータを取得する方法

Nuxt のデータフェッチ機能は、ページ遷移時に必要なデータを取得してから画面を表示するため、ユーザー体験の向上に役立ちます。しかし、デフォルトの useFetch は非同期処理が完了するまでナビゲーションをブロックするため、場合によっては遷移が遅く感じられることがあります。
useLazyFetch はこの課題を解決し、ナビゲーションを即座に行いながらバックグラウンドでデータを取得できるため、UXの改善やパフォーマンス最適化に役立ちます。


まず結論:useLazyFetch のポイント

  • ナビゲーションをブロックしない:データ取得完了を待たずにページ遷移が可能
  • 非同期データの遅延読み込みに最適:初期表示を高速化しつつ、必要なデータは後から取得
  • useFetch と同じAPIで使いやすい:既存のコードからの移行もスムーズ
  • クライアントサイドでの保留状態管理が必要:データが未取得の状態を考慮したUI設計が重要
  • SSR時は注意が必要:サーバーサイドレンダリングではデータ取得のタイミングに影響が出る可能性あり

いつ使うべきか?使わない方がよいケース

使うべきケース

  • ページ遷移のレスポンスを優先したいとき
  • 大量のデータや重いAPI呼び出しで初期表示を遅くしたくない場合
  • ユーザーがすぐに画面を操作できるようにしたいインタラクティブなUI
  • ページの一部だけ遅延読み込みしたい場合(例:コメントや関連情報など)

使わない方がよいケース

  • SEOや初期表示の完全なデータ取得が必須なページ
  • SSRで完全なHTMLを生成したい場合(useLazyFetch はサーバー側での完了を保証しないため)
  • データがないとUIが成立しない重要な情報を扱う場合(保留状態のUI設計が難しいとき)

実務でよくあるユースケースとサンプルコード

1. ブログ記事一覧の遅延読み込み

初期表示はタイトルだけ表示し、記事の詳細はバックグラウンドで取得して後から表示する例です。

<script setup lang="ts">
const { data: posts, pending, error } = await useLazyFetch('/api/posts')
</script>

<template>
  <div>
    <h1>ブログ記事一覧</h1>
    <div v-if="pending">記事を読み込み中...</div>
    <ul v-else>
      <li v-for="post in posts" :key="post.id">{{ post.title }}</li>
    </ul>
    <div v-if="error">記事の取得に失敗しました。</div>
  </div>
</template>

2. ユーザープロフィールの部分的な遅延読み込み

プロフィールの基本情報はSSRで取得し、詳細情報はクライアント側で遅延取得するパターン。

<script setup lang="ts">
// SSRで取得済みの基本情報
const basicProfile = useAsyncData('basicProfile', () => $fetch('/api/profile/basic'))

// 詳細情報は遅延取得
const { data: detailedProfile, pending } = await useLazyFetch('/api/profile/details')
</script>

<template>
  <div>
    <h2>{{ basicProfile.value.name }}</h2>
    <div v-if="pending">詳細情報を読み込み中...</div>
    <div v-else>
      <p>趣味: {{ detailedProfile.hobbies }}</p>
      <p>自己紹介: {{ detailedProfile.bio }}</p>
    </div>
  </div>
</template>

3. ページ内のコメントセクションを遅延読み込み

コメントはページ表示後に取得し、ユーザーの操作を妨げないようにする例。

<script setup lang="ts">
const { data: comments, pending } = await useLazyFetch(`/api/posts/${postId}/comments`)
</script>

<template>
  <section>
    <h3>コメント</h3>
    <div v-if="pending">コメントを読み込み中...</div>
    <ul v-else>
      <li v-for="comment in comments" :key="comment.id">{{ comment.text }}</li>
    </ul>
  </section>
</template>

よくある落とし穴・注意点

1. SSRとHydrationのズレに注意

useLazyFetch はサーバー側でのデータ取得完了を待たないため、SSR時にデータが未取得のままHTMLが生成されることがあります。
その結果、クライアントでのHydration時にUIが一時的に空やローディング状態となり、ユーザーに違和感を与える可能性があります。
このため、SEOが重要なページや初期表示の完全なデータ取得が必要な場合は、useFetch を使うか、useLazyFetch の利用を慎重に検討してください。

2. 保留状態のUI設計が必須

useLazyFetch はデータがまだ取得されていない状態を許容するため、pendingerror の状態を適切にハンドリングするUI設計が不可欠です。
これを怠ると、ユーザーに空白やエラー表示が不自然に見えることがあります。

3. パフォーマンスへの影響

遅延取得は初期表示を高速化しますが、データ取得が遅れることでユーザーが必要な情報を得るまでの時間が長くなる場合があります。
特にネットワークが遅い環境では、遅延読み込みのメリットとデメリットをよく検討しましょう。


まとめ

useLazyFetch は Nuxt のデータフェッチ機能の中でも、ナビゲーションをブロックせずに非同期データを取得できる強力なツールです。
初期表示の高速化やユーザー体験の向上に役立ちますが、SSRとの兼ね合いや保留状態のUI設計には注意が必要です。
実務では、遅延読み込みが適切なケースを見極めて使うことで、パフォーマンスとUXのバランスを最適化できます。

適切に活用して、より快適な Nuxt アプリケーションを構築しましょう。


useLazyFetchuseFetch と同じAPIを持つため、既存の useFetch を置き換えるだけで簡単に遅延読み込みを導入できます。
ただし、保留状態のUI対応は必ず行いましょう。