🍩
Nuxt3のuseFetchのlazyオプション
Nuxt3の useFetch
では lazy
オプション が提供されています。
whether to resolve the async function after loading the route, instead of blocking client-side navigation
クライアントのページ遷移をブロックすることなくページ遷移後に非同期関数を解決します
ちょっとわかりにくいので通常のuseFetch
の挙動と比較して見てみましょう
普通にuseFetchを利用
まずは、 server/api/lazy.ts
として以下のレスポンスに2秒ぐらいかかかるAPIを用意します。
server/api/lazy.ts
export default defineEventHandler(async () => {
const time = new Date()
await new Promise(resolve => setTimeout(resolve, 2000));
return {
time
}
})
以下のような遷移前のページを用意して
pages/index.vue
<template>
<NuxtLink to="/lazy">表示の遅いページに遷移</NuxtLink>
</template>
遷移後のページも用意しておきます
pages/lazy.vue
<template>
<pre>{{ data.time }}</pre>
</template>
<script setup>
const { data } = await useFetch('/api/lazy')
</script>
遷移前のページから遷移後のページに遷移しようとすると2秒後にページが表示されます。
lazyオプションを利用
では、lazyオプションを利用した場合どうなるか見ていきましょう。
pages/lazy.vue
<template>
<pre>{{ data?.time }}</pre>
</template>
<script setup>
const { data } = await useFetch('/api/lazy', {
lazy: true
})
</script>
遷移前のページから遷移後のページに遷移しようとすると即座にページが表示されますがページの内容は空のままです。そして2秒後にページの内容が表示されます。
また1度戻ってから再度移動をすると、前回のキャッシュを元にページの内容を表示しておき最新の情報を取得してからページを表示しています。
lazyオプションを利用する際の注意
lazyオプションを利用する際には
- レスポンスがリアクティブなデータである事
- キャッシュがあればひとまずキャッシュが返ってくること
を注意しなくてはいけません。
以下のようにdataの値を別の変数に入れて利用しようとします。
pages/lazy.vue
<template>
<pre>{{ data?.time }}</pre>
<pre>{{ data2?.time }}</pre>
</template>
<script setup>
const { data } = await useFetch('/api/lazy', {
lazy: true
})
const data2 = data.value
</script>
ページ表示時はうまく表示が行えているような感じがしますが、ページ遷移時にdata2にはキャッシュされている前回の値が格納されてしまっています。
リアクティブなデータを別の変数に入れる場合は、ちゃんとcomputed
を利用する必要があるので注意してください。
pages/lazy.vue
<template>
<pre>{{ data?.time }}</pre>
<pre>{{ data2?.time }}</pre>
</template>
<script setup>
const { data } = await useFetch('/api/lazy', {
lazy: true
})
const data2 = computed(()=>{
return data.value
})
</script>
Discussion