useLazyAsyncData
この useAsyncData のラッパーは、ナビゲーションを即座にトリガーします。
説明
デフォルトでは、useAsyncData は非同期ハンドラーが解決されるまでナビゲーションをブロックします。useLazyAsyncData は、lazy オプションを true に設定することで、ハンドラーが解決される前にナビゲーションをトリガーする useAsyncData のラッパーを提供します。
useLazyAsyncData は useAsyncData と同じシグネチャを持ちます。
例
<script setup lang="ts">
/* フェッチが完了する前にナビゲーションが発生します。
コンポーネントのテンプレート内で 'pending' と 'error' の状態を直接処理します
*/
const { status, data: count } = await useLazyAsyncData('count', () => $fetch('/api/count'))
watch(count, (newCount) => {
// count は最初は null かもしれないので、
// その内容にすぐにはアクセスできませんが、監視することはできます。
})
</script>
<template>
<div>
{{ status === 'pending' ? 'Loading' : count }}
</div>
</template>
useLazyAsyncData はコンパイラによって変換される予約関数名であるため、自分の関数に useLazyAsyncData という名前を付けるべきではありません。
tips
このセクションは公式ドキュメントの翻訳ではなく、本サイト独自の補足記事です。
useLazyAsyncData の補足解説
Nuxt での非同期データ取得は、ページの初期表示やナビゲーション時に重要な役割を果たします。useAsyncData はデータ取得が完了するまでナビゲーションを待機させるため、ユーザー体験としては「読み込み中」の状態が続きます。これに対し、useLazyAsyncData はデータ取得を遅延させ、ナビゲーションを即座に進めることができるため、UXの向上やパフォーマンス改善に役立ちます。
本記事では、useLazyAsyncData の特徴や使いどころ、実務での具体的なユースケース、そして注意すべきポイントを丁寧に解説します。
まず結論:useLazyAsyncData のポイント
-
ナビゲーションをブロックせずに非同期データを取得できる
ページ遷移を即座に行い、データはバックグラウンドで取得される。 -
useAsyncDataと同じシグネチャで使いやすい
既存のuseAsyncDataとほぼ同様のAPIで利用可能。 -
初期値は
nullなどの未取得状態になるため、状態管理が必要
データがまだ取得されていない状態を考慮したUI設計が求められる。 -
SSR(サーバーサイドレンダリング)ではデータが遅延するため、SEOや初期表示に影響が出る可能性がある
SEO重視のページでは使いどころに注意。 -
パフォーマンス改善やユーザー体験向上に効果的なケースが多い
特に重いAPI呼び出しやユーザー操作後のデータ取得に適している。
いつ使うべきか・使わない方がよいケース
使うべきケース
-
ユーザー操作後にデータを取得したい場合
例えば、フィルターや検索条件を変更した後に結果を取得する際、即座に画面遷移やUI更新を行い、データは遅れて反映させたいとき。 -
ページ遷移のレスポンスを優先したい場合
ページの初期表示速度を重視し、データ取得は非同期で行いたい場合。 -
重いAPI呼び出しや外部サービスのレスポンスが遅い場合
ユーザーの待ち時間を減らし、UXを向上させるため。
使わない方がよいケース
-
SEOが重要な静的ページやSSRでの初期レンダリング
データが遅延すると、検索エンジンに正しい情報が渡らずSEOに悪影響が出る可能性がある。 -
データが必須で、取得前に画面を表示すると意味がない場合
例えば、詳細ページの必須情報など。 -
Hydration(サーバーとクライアントの状態同期)が複雑になるケース
遅延取得によりサーバーとクライアントで状態が異なると、UIの不整合が起きやすい。
実務でよくあるユースケースとサンプルコード
1. ユーザー操作後のデータ取得(検索フォーム)
ユーザーが検索条件を入力してから結果を取得する場合、即座に画面を切り替えつつ、結果は遅れて表示します。
<script setup lang="ts">
import { ref, watch } from 'vue'
const query = ref('')
const { data: results, status } = useLazyAsyncData('searchResults', () => $fetch(`/api/search?q=${query.value}`))
watch(query, (newQuery) => {
if (newQuery) {
// クエリが変わったら遅延データ取得をトリガー
results.value = null
status.value = 'pending'
useLazyAsyncData('searchResults', () => $fetch(`/api/search?q=${newQuery}`))
}
})
</script>
<template>
<input v-model="query" placeholder="検索キーワード" />
<div v-if="status === 'pending'">検索中...</div>
<ul v-else>
<li v-for="item in results" :key="item.id">{{ item.name }}</li>
</ul>
</template>
2. ページ遷移時に即座に画面を表示し、データは後から取得
初期表示を高速化し、データは非同期で取得して表示します。
<script setup lang="ts">
const { data: user, status } = useLazyAsyncData('user', () => $fetch('/api/user'))
</script>
<template>
<div>
<p v-if="status === 'pending'">ユーザー情報を読み込み中...</p>
<p v-else>ようこそ、{{ user.name }}さん!</p>
</div>
</template>
3. 重いAPI呼び出しの遅延実行
外部APIのレスポンスが遅い場合、画面表示を優先し、API結果は後から反映。
<script setup lang="ts">
const { data: stats, status } = useLazyAsyncData('stats', () => $fetch('https://external.api/stats'))
</script>
<template>
<div>
<p v-if="status === 'pending'">統計情報を取得中...</p>
<pre v-else>{{ stats }}</pre>
</div>
</template>
よくある落とし穴・注意点
SSRとHydrationのズレ
useLazyAsyncData はサーバー側でのデータ取得を遅延させるため、SSR時にはデータが存在しない状態でHTMLが生成されます。クライアント側でデータが取得されると、サーバーとクライアントの状態が異なり、HydrationエラーやUIのちらつきが発生することがあります。
SEOへの影響
SEOを重視するページでは、初期HTMLに必要なデータが含まれないため、検索エンジンのクロール時に情報が不足する可能性があります。SEOが重要なページでは useAsyncData を使い、サーバーでデータを取得してからレンダリングすることを推奨します。
パフォーマンスとUXのバランス
遅延取得はUX向上に寄与しますが、データが遅れて表示されることでユーザーが混乱する場合もあります。ローディング表示やプレースホルダーを適切に用意し、ユーザーに状態を明示することが重要です。
予約関数名の注意
useLazyAsyncData は Nuxt の予約関数名です。自分の関数や変数に同名を付けるとコンパイルエラーや予期せぬ動作を招くため避けてください。
まとめ
useLazyAsyncData は、非同期データ取得を遅延させてナビゲーションを即座に行うことで、ユーザー体験の向上やパフォーマンス改善に役立つ強力な機能です。特にユーザー操作後のデータ取得や重いAPI呼び出しの遅延実行に適しています。
ただし、SSRやSEOを重視するページでは使いどころに注意が必要であり、HydrationのズレやUIの状態管理にも配慮が求められます。適切に使い分けることで、Nuxt アプリケーションの品質を高めることができるでしょう。
useLazyAsyncData を使う際は、データの未取得状態を考慮したUI設計(ローディング表示やエラーハンドリング)を必ず行い、ユーザーにわかりやすい体験を提供しましょう。
※このページは Nuxt.js 公式ドキュメントの翻訳ページです。
公式ドキュメントの該当ページはこちら:
https://nuxt.com/docs/3.x/api/composables/use-lazy-async-data