Skip to content

지연 로딩

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로 공통 라이브러리 분리

TIENIPIA QUALIFIED STANDARD