Single Page Application의 가장 큰 특징으로 페이지 진입시 리소스를 한번에 다운을 받아서 자연스러운 페이지 전환을 시켜 준다는 것이다.
하지만 프로젝트의 규모가 커지면 커질 수 록 리소스 다운로드에 많은 시간이 소요되어서 SPA의 장점이자 단점으로 작용한다. SPA의 대표적인 프레임워크/라이브러리로 꼽히는 Angular, React, Vue에서는 이와 같은 단점을 보완하기 위해 지연된 로딩(Lazy Loading)을 활용한다.
지연된 로딩이란 해당 기능이 필요한 타이밍에 로딩하여 사용하는 방법으로, 불필요하게 index페이지에서 당장 사용하지 않는 리소스 다운 시간을 단축시켜 준다.
import MainPage from './components/MainPage.vue'
import InfoPage from './components/InfoPage.vue'
import PurchasePage from './components/PurchasePage.vue'
const router = new VueRouter({
routes: [
{ path: '/main', component: MainPage },
{ path: '/info', component: InfoPage },
{ path: '/purchase', component: PurchasePage }
]
})
상단에서 MainPage, InfoPage, PurchasePage를 모두 import하고 있기 때문에 해당 경로에 진입하지 않더라도 모든 컴포넌트 리소스를 다운받게된다. 규모가 작은 프로젝트라면 이렇게 하더라도 큰 문제가 없겠지만 규모가 커질수록 이와 같은 코드는 성능적으로 문제가 생기게 된다.
const router = new VueRouter({
routes: [
{ path: '/main', component: () => import('./components/MainPage.vue') },
{ path: '/info', component: () => import('./components/InfoPage.vue')},
{ path: '/purchase', component: () => import('./components/PurchasePage.vue') }
]
})
위와 같이 컴포넌트 import 코드를 routes 내에서 하면 해당 경로로 들어왔을 때 리소스를 다운받게 된다. 라우트 설정에 컴포넌트를 반환하는 함수를 정의하면 매칭되는 경로로 들어왔을 때 컴포넌트를 import와 함께 반환하게 된다.
개발자 콘솔을 열어서 확인해보면 경로가 매칭될 때 마다 다운 받는 것을 알수 있다.
<template>
<div id="nav">
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link> |
<router-link to="/one">One</router-link> |
<router-link to="/two">Two</router-link> |
<router-link to="/three">Three</router-link>
</div>
<router-view/>
</template>
<style>
<template>
<div class="one">
<h1>This is an one page</h1>
</div>
</template>
two, three같은 경우에도 위와 같이 생성
one, two, three를 라우터에 추가해준 뒤 해당 라우터는 특별한 주석을 / webpackChunkName: "num" / 로 동일하게 하여 그룹핑해 준다.
import { createRouter, createWebHistory } from 'vue-router'
import Home from '../views/Home.vue'
const routes = [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/about',
name: 'About',
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
},
{
path: '/one',
name: 'One',
component: () => import(/* webpackChunkName: "num" */ '../views/One.vue')
},
{
path: '/two',
name: 'Two',
component: () => import(/* webpackChunkName: "num" */ '../views/Two.vue')
},
{
path: '/three',
name: 'Three',
component: () => import(/* webpackChunkName: "num" */ '../views/Three.vue')
}
]
const router = createRouter({
history: createWebHistory(process.env.BASE_URL),
routes
})
export default router
그룹핑된 One, Two, Three 메뉴는 One에서 num.js 호출하고 그 뒤로는 호출하지 않는 것을 확인 수 있다.