지연 로딩
12.3.1. 라우트 레벨 코드 분할
- 모든 라우트 컴포넌트는 동적
import()를 사용하여 지연 로딩합니다. - 정적
import로 라우트 컴포넌트를 불러오는 것은 허용하지 않습니다. - 동적
import()를 사용하면 Vite가 자동으로 라우트별 청크를 생성합니다.
typescript
// 올바른 예: 동적 import
{
path: '/dashboard',
name: 'Dashboard',
component: () => import('@/views/DashboardView.vue'),
meta: { title: '대시보드', requiresAuth: true },
}
// 잘못된 예: 정적 import (사용 금지)
import DashboardView from '@/views/DashboardView.vue'
{
path: '/dashboard',
name: 'Dashboard',
component: DashboardView,
}- 예외적으로 항상 렌더링되는 최상위 레이아웃 컴포넌트는 정적
import를 허용합니다.
12.3.2. 로딩 상태 처리
- 지연 로딩 중 사용자에게 로딩 상태를 표시해야 합니다.
defineAsyncComponent를 사용하여 로딩 컴포넌트와 에러 컴포넌트를 지정합니다.- 네트워크 지연이 짧을 경우 로딩 화면이 깜빡이는 것을 방지하기 위해
delay옵션을 설정합니다.
typescript
import { defineAsyncComponent } from 'vue'
import LoadingSpinner from '@/components/common/LoadingSpinner.vue'
import ErrorFallback from '@/components/common/ErrorFallback.vue'
const AsyncDashboard = defineAsyncComponent({
loader: () => import('@/views/DashboardView.vue'),
loadingComponent: LoadingSpinner,
errorComponent: ErrorFallback,
delay: 200,
timeout: 10000,
})| 옵션 | 설명 | 기본값 |
|---|---|---|
loader | 컴포넌트를 반환하는 함수 | 필수 |
loadingComponent | 로딩 중 표시할 컴포넌트 | 없음 |
errorComponent | 로드 실패 시 표시할 컴포넌트 | 없음 |
delay | 로딩 컴포넌트 표시 지연 시간(ms) | 200 |
timeout | 타임아웃 시간(ms) | 무제한 |
12.3.3. 프리로드 전략
- 사용자 경험을 향상하기 위해 다음 페이지의 청크를 미리 로드하는 전략을 적용합니다.
- 3가지 프리로드 방식 중 프로젝트 특성에 맞는 방식을 선택합니다.
링크 호버 시 프리로드
vue
<script setup lang="ts">
function preloadRoute(importFn: () => Promise<unknown>) {
importFn()
}
</script>
<template>
<RouterLink
:to="{ name: 'UserList' }"
@mouseenter="preloadRoute(() => import('@/views/user/UserListView.vue'))"
>
사용자 목록
</RouterLink>
</template>뷰포트 진입 시 프리로드
typescript
// src/composables/useRoutePreload.ts
import { useIntersectionObserver } from '@vueuse/core'
import type { Ref } from 'vue'
export function useRoutePreload(
target: Ref<HTMLElement | null>,
importFn: () => Promise<unknown>
) {
let loaded = false
useIntersectionObserver(target, ([entry]) => {
if (entry.isIntersecting && !loaded) {
loaded = true
importFn()
}
})
}HTML link 태그 프리페치
- Vite는 빌드 시
<link rel="modulepreload">를 자동으로 삽입합니다. - 추가 프리페치가 필요한 경우
vite-plugin-preload등의 플러그인을 사용합니다.
12.3.4. 청크 네이밍
- Vite 환경에서는
rollupOptions.output.chunkFileNames를 사용하여 청크 이름 패턴을 설정합니다. - 디버깅과 번들 분석을 위해 의미 있는 청크 이름을 부여합니다.
typescript
// vite.config.ts
import { defineConfig } from 'vite'
export default defineConfig({
build: {
rollupOptions: {
output: {
chunkFileNames: 'js/[name]-[hash].js',
entryFileNames: 'js/[name]-[hash].js',
assetFileNames: 'assets/[name]-[hash].[ext]',
manualChunks: {
'vendor-vue': ['vue', 'vue-router', 'pinia'],
},
},
},
},
})| 항목 | 규칙 |
|---|---|
| 라우트 컴포넌트 | 동적 import() 필수 |
| 로딩 컴포넌트 | defineAsyncComponent로 지정 |
| 프리로드 | 호버 또는 뷰포트 진입 방식 적용 |
| 청크 네이밍 | rollupOptions로 패턴 설정 |
| 벤더 분리 | manualChunks로 공통 라이브러리 분리 |