🍩

Nuxt3のuseFetchのlazyオプション

2024/01/24に公開

Nuxt3の useFetch では lazyオプション が提供されています。

https://nuxt.com/docs/api/composables/use-fetch#params

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