Skip to content

라우트 지연 로딩 ​

번들러로 앱을 빌드하면 JavaScript 번들이 꽤 커질 수 있고, 이는 페이지 로드 시간에 영향을 줍니다. 각 라우트의 컴포넌트를 별도 청크로 분리하고 해당 라우트를 방문했을 때만 로드할 수 있다면 더 효율적일 것입니다.

Vue Router는 dynamic import를 기본 지원하므로, 정적 import를 동적 import로 바꿀 수 있습니다:

js
// 다음을
// import UserDetails from './views/UserDetails.vue'
// 이렇게 바꿉니다
const UserDetails = () => import('./views/UserDetails.vue')

const router = createRouter({
  // ...
  routes: [
    { path: '/users/:id', component: UserDetails },
    // 또는 라우트 정의에서 직접 사용하세요
    { path: '/users/:id', component: () => import('./views/UserDetails.vue') },
  ],
})

component(및 components) 옵션은 컴포넌트 Promise를 반환하는 함수를 받으며, Vue Router는 해당 페이지에 처음 진입할 때만 이를 가져온 뒤 캐시된 버전을 사용합니다. 즉 Promise를 반환하기만 한다면 더 복잡한 함수도 사용할 수 있습니다:

js
const UserDetails = () =>
  Promise.resolve({
    /* 컴포넌트 정의 */
  })

일반적으로는 모든 라우트에 대해 항상 동적 import를 사용하는 것이 좋습니다.

Vite나 webpack 같은 번들러를 사용하면 이는 자동으로 코드 분할의 이점을 얻게 됩니다.

async 컴포넌트와의 관계 ​

Vue Router의 지연 로딩은 Vue의 async 컴포넌트와 비슷해 보일 수 있지만, 둘은 별개의 기능입니다. async 컴포넌트를 라우트 컴포넌트로 사용하지 마세요. async 컴포넌트는 라우트 컴포넌트 안에서 사용할 수는 있지만, 라우트 컴포넌트 자체는 단순히 함수여야 합니다.

함수형 컴포넌트와의 관계 ​

흔한 경우는 아니지만 함수형 컴포넌트를 라우트 컴포넌트로 사용할 수 있습니다. 하지만 Vue Router는 함수형 컴포넌트와 지연 로딩을 구분할 방법이 필요합니다. 함수형 컴포넌트를 사용하려면 함수에 displayName을 부여해야 합니다:

ts
const AboutPage: FunctionalComponent = () => {
  return h('h1', {}, 'About')
}
AboutPage.displayName = 'AboutPage'

같은 청크로 컴포넌트 묶기 ​

같은 라우트 아래 중첩된 모든 컴포넌트를 같은 청크로 묶어, 한 번의 요청으로 모두 로드되게 하고 싶을 수 있습니다.

Vite에서 ​

rollupOptions 아래에서 청크를 정의할 수 있습니다:

js
export default defineConfig({
  build: {
    rollupOptions: {
      // https://rollupjs.org/guide/en/#outputmanualchunks
      output: {
        manualChunks: {
          'group-user': [
            './src/UserDetails',
            './src/UserDashboard',
            './src/UserProfileEdit',
          ],
        },
      },
    },
  },
})

webpack에서 ​

chunk 이름을 특수 주석 문법으로 지정할 수 있습니다:

js
const UserDetails = () =>
  import(/* webpackChunkName: "group-user" */ './UserDetails.vue')
const UserDashboard = () =>
  import(/* webpackChunkName: "group-user" */ './UserDashboard.vue')
const UserProfileEdit = () =>
  import(/* webpackChunkName: "group-user" */ './UserProfileEdit.vue')

webpack은 같은 chunk 이름을 가진 모든 async 모듈을 동일한 async chunk로 묶습니다.

모두를 위한 문서 한글화