Skip to content
sumnail

Vue3の非同期コンポーネントで遅延ローディングを実装

created at : 2024/07/19

Vue3
遅延読み込み
非同期処理

Vue3の遅延ローディングを使って、非同期コンポーネントを実装してみます。
画像や動画などを遅延ローディングすることで、ページの読み込み速度を向上させることが出来る想定です。

遅延読み込みサンプル

コンポーネントの読み込み時間を3秒に設定して、待機時間を5秒に設定してみます。

5秒以内に遅延コンポーネントが読み込まれると、「読み込み完了」が表示されます。

読み込み完了

遅延読み込みの例外処理

コンポーネントの読み込み時間を5秒に設定して、待機時間を3秒に設定してみます。

待機時間内に読み込みが出来ないため、errorコンポーネントが表示されます。

しかし、読み込みエラーが発生した場合も遅延ローディング自体が打ち切られる訳ではないため、5秒後に遅延読み込みコンポーネントの「読み込み完了」が表示されます。

実際の遅延読み込みでは、何かしらの例外処理でエラーが発生しているのでこのような挙動は想定されない認識です。

読み込み完了

実験に使用したサンプルコード

vue
<template>
  <AsyncComp/>
</template>

<script setup lang="ts">
import { defineAsyncComponent } from 'vue'
import Spinner from './Spinner.vue'
import Error from './Error.vue'

interface Props {
  lazytime: number
  delay: number
  timeout: number
}

const props = defineProps<Props>()

const sleep = (ms: number) => new Promise(resolve => setTimeout(resolve, ms))

const AsyncComp = defineAsyncComponent({
  loader: () => sleep(props.lazytime).then(() => import('./Async.vue')),
  loadingComponent: Spinner,
  delay: props.delay,
  errorComponent: Error,
  timeout: props.timeout
})
</script>
vue
<template>
  <p>読み込み完了</p>
</template>
<style scoped>
p {
  color: green;
  font-weight: bold;
}
</style>
vue
<template>
  <p>Error!!!</p>
</template>
<style scoped>
p {
  color: red;
  font-weight: bold;
}
</style>
vue
<template>
  <v-progress-circular
    class="spinner"
    indeterminate
  ></v-progress-circular>
</template>

<script setup lang="ts">
</script>

<style scoped>
.spinner {
  margin: 0 auto;
  color: var(--main-color);
}
</style>

参考

https://vuejs.org/guide/components/async