defineAsyncComponentによる非同期コンポーネント
defineAsyncComponent()、loadingComponent、errorComponent、delayとtimeoutオプション
「defineAsyncComponentによる非同期コンポーネント」はCoddyKit上の無料Vue Academyレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはVue Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Vue Academyコースには全4レッスンが含まれています。
非同期コンポーネントを使う理由
defineAsyncComponentを使うと、コンポーネントを遅延読み込みできます。コンポーネントが初めて描画されるときにだけ、そのコードが取得されます。
これにより、ルート単位およびコンポーネント単位でコード分割でき、初期バンドルのサイズを小さくして初回ペイントを高速化できます。
ローダー関数形式
最も簡単な使い方は、動的なimport()を返すローダー関数を渡す方法です。Vite/webpackは、そのimportを自動的に独立したチャンクへコード分割します。
<script setup>
import { defineAsyncComponent } from 'vue'
const SettingsModal = defineAsyncComponent(() =>
import('./SettingsModal.vue')
)
</script>
<template>
<SettingsModal v-if="showSettings" />
</template>オプションオブジェクト形式
より細かく制御するには、オプションオブジェクトを渡します。主なフィールドは次のとおりです。
- loader — 動的import関数
- loadingComponent — 読み込み中に表示するコンポーネント
- errorComponent — 読み込みに失敗した場合に表示するコンポーネント
- delay / timeout — タイミングを制御するオプション
import { defineAsyncComponent } from 'vue'
import Loading from './Loading.vue'
import ErrorView from './ErrorView.vue'
const AsyncChart = defineAsyncComponent({
loader: () => import('./Chart.vue'),
loadingComponent: Loading,
errorComponent: ErrorView,
delay: 200,
timeout: 5000
})delay:スピナーの一瞬の表示を防ぐ
delayオプション(デフォルトは200ミリ秒)は、loadingComponentを表示するまでVueが待機する時間です。チャンクがdelayより速く読み込まれれば、スピナーはまったく表示されません。
delay: 0にすると、読み込み状態をすぐに表示できます。
const AsyncPanel = defineAsyncComponent({
loader: () => import('./Panel.vue'),
loadingComponent: Spinner,
// wait 300ms before showing Spinner
delay: 300
})timeout:遅い読み込みを失敗扱いにする
timeoutオプションは、待機する最大時間を設定します。loaderがtimeoutミリ秒以内に解決しない場合、errorComponentが表示され、エラーがログに記録されます。
デフォルトではtimeoutは設定されておらず、読み込みは無期限に待機します。
const AsyncReport = defineAsyncComponent({
loader: () => import('./Report.vue'),
errorComponent: ErrorView,
// fail if not loaded within 10s
timeout: 10000
})onErrorコールバック
loaderがrejectされたときにonErrorハンドラーが実行されます。ハンドラーはerror、retry関数、fail関数、現在のattempt回数を受け取ります。
不安定なネットワークに対する、回数制限付きのリトライ処理を実装する場所です。
const AsyncWidget = defineAsyncComponent({
loader: () => import('./Widget.vue'),
onError(error, retry, fail, attempts) {
if (attempts <= 3) {
retry() // try loading again
} else {
fail() // give up, show errorComponent
}
}
})リトライと失敗の判断
onError内では、retry()またはfail()のどちらか一方を必ず呼び出す必要があります(どちらも呼び出さない場合も失敗になります)。よくある戦略は、ネットワークエラーには数回リトライし、リトライでは解決できない構文エラーやチャンクエラーの場合はすぐに失敗させることです。
onError(error, retry, fail, attempts) {
const isNetwork = /Loading chunk/.test(error.message)
if (isNetwork && attempts <= 2) {
retry()
} else {
fail()
}
}Suspenseとの組み合わせ
非同期コンポーネントをSuspenseバウンダリの内側に配置すると、代わりにバウンダリが読み込み状態を制御します。この場合、コンポーネント自身のloadingComponentは無視され、Suspenseのfallbackが優先されます。
<template>
<Suspense>
<AsyncChart /> <!-- loadingComponent ignored here -->
<template #fallback>Loading chart...</template>
</Suspense>
</template>デバッグ用の名前付きチャンク
マジックコメントを使って、生成されるチャンクに名前を付けられます。これにより、ネットワークリクエストやバンドルレポートを読みやすくできます。
const AsyncEditor = defineAsyncComponent(() =>
import(
/* webpackChunkName: "editor" */
'./RichTextEditor.vue'
)
)非同期コンポーネントとprops
非同期コンポーネントは、通常のコンポーネントとまったく同じようにpropsを受け取り、イベントを発行します。実際のコンポーネントが解決されると、Vueがすべてを透過的に転送するため、呼び出し側を変更する必要はありません。
<template>
<AsyncProfile
:user-id="id"
@save="handleSave"
/>
</template>
<!-- AsyncProfile resolves to the real component, props/events pass through -->ベストプラクティス:ファーストビューの遅延読み込みは慎重に
画面外にあるコンポーネント、操作の背後にあるコンポーネント(モーダルやタブ)、または使用頻度の低いコンポーネントを遅延読み込みします。ファーストビューの重要なUIを遅延読み込みするのは避けてください。余分なラウンドトリップによって、体感パフォーマンスが低下する可能性があります。
// Good candidate: modal only opened on click
const Modal = defineAsyncComponent(() => import('./Modal.vue'))
// Poor candidate: hero shown immediately on load
// import Hero directly instead理解度チェック
defineAsyncComponentについての理解度を確認しましょう。
まとめ
defineAsyncComponentを使った非同期コンポーネントの読み込みについて学びました。
- ローダー形式では動的な
import()を返し、コード分割を行います - オプション形式では
loadingComponent、errorComponent、delay、timeoutを追加できます delayはスピナーの一瞬の表示を防ぎ、timeoutは遅い読み込みを失敗扱いにしますonError(error, retry, fail, attempts)でリトライまたは失敗のロジックを実装します- Suspenseの内側では、バウンダリのfallbackが読み込みUIを引き継ぎます
よくある質問
「defineAsyncComponentによる非同期コンポーネント」レッスンは無料ですか?
はい。「defineAsyncComponentによる非同期コンポーネント」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Vue Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Vue Academyコースには全4レッスンが含まれています。
「defineAsyncComponentによる非同期コンポーネント」で何を学びますか?
defineAsyncComponent()、loadingComponent、errorComponent、delayとtimeoutオプション ブラウザで直接実行するハンズオンコードでVue Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Vue Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのVue Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。
「defineAsyncComponentによる非同期コンポーネント」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このVue Academyレッスンでコードを書いて実行できますか?
はい。すべてのVue Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- Vue Suspenseコンポーネント
- defineAsyncComponentによる非同期コンポーネント
- renderToWebStreamによるストリーミングSSR
- 遅延ハイドレーション戦略