🌊
Vue RouterでLazy Loadingを使ってパスが呼ばれたときに始めてコンポーネントをインポートする
インポートが多いと
Nuxtを使わずにVue Routerで記述すると、main.jsなどの頭に大量のimport文地獄が発生することがあります。すぐに使用しないコンポーネントなどを大量に読み込むため、最初に読み込むファイルのサイズが大きくなってしまいかねません。
表示に必要なコンポーネントを必要なタイミングで読み込むほうが、効率が良いと言えます。そこでVue RouterにあるLazy Loading(レイジー・ロード)を使用することができるようです。
日本語のドキュメントだと「遅延ローディングルート」と言うらしいですね。
使用前
コードとしてmain.jsのサンプルです。こんな感じでHomeとTestというコンポーネントをインポートしています。
import { createApp } from 'vue'
import App from './App.vue'
import {createRouter, createWebHistory} from 'vue-router'
import Home from "./components/Home.vue";
import Test from "./components/Test.vue";
import './assets/main.css'
const app = createApp(App);
const routes = [
{ path: '/', component: Home },
{ path: '/test', component: Test },
]
const router = createRouter({
history: createWebHistory(),
routes
})
app.use(router)
app.mount('#app')
使用後
インポート文のところがconstに入れ替わっています。
import { createApp } from 'vue'
import App from './App.vue'
import {createRouter, createWebHistory} from 'vue-router'
// この部分を変更
const Home = () => import("./components/Home.vue");
const Test = () => import("./components/Test.vue");
import './assets/main.css'
const app = createApp(App);
const routes = [
{ path: '/', component: Home },
{ path: '/test', component: Test },
]
const router = createRouter({
history: createWebHistory(),
routes
})
app.use(router)
app.mount('#app')
公式ドキュメントによれば、この記法が成り立つ理屈としてはこのように説明されています。
webpack によって自動的にコード分割される非同期コンポーネントを定義する方法です
Vueの非同期コンポーネント機能とwebpack 2の動的importを組み合わせることで実現するようです。
コンポーネントごとにも応用
同じ考え方は、ルーティングごとだけでなく、コンポーネントにも同じことができます。defineAsyncComponentを使用して以下のように書けます。
<script setup>
import { defineAsyncComponent } from "vue";
const description = 'こんにちはWorld';
const Icon = defineAsyncComponent(
() => import('../icons/Icon.vue')
);
</script>
<template>
<section>
<Icon />
<div>{{ description }}</div>
</section>
</template>
<style scoped>
</style>
まとめ
小規模であればそれほど問題にはならないことかと思います。しかしCore Web Vitalsのあと少しだけでもスコアを上げたい時とかに見直してみるポイントしては、覚えておくほうが良いTipsかと思います。
Discussion