
Nuxt 3는 본질적으로 최적화를 지향하는 프레임워크로 자동 임포트, 코드 스플리팅, SSR(Server Side Rendering) 및 SSG(Static Site Generation), 파일 기반 라우팅, 컴포넌트 지연 로딩, Vite 기반의 빠른 빌드 및 HMR(Hot Module Replacement) 등 다양한 최적화 기능이 기본적으로 내장되어 있다.
이 중에서도 composables는 중복 코드 제거와 유지보수성을 높이는 데 핵심적인 역할을 하며, 실제 프로젝트에서도 활발히 활용되고 있다. 해당 개념은 이미 정리한 바 있어 이번 글에서는 실무에서 더 직접적으로 성능 개선에 기여할 수 있는 요소들, 특히 동적 컴포넌트와 keep-alive에 대해 다뤄보려 한다.
동적 컴포넌트의 장점
동적 컴포넌트는 하나의 컴포넌트 영역에서 여러 유형의 UI 요소를 조건에 따라 렌더링할 수 있도록 하여, UI 로직을 간결하고 모듈화할 수 있다. 이는 코드 중복을 줄이고 재사용성을 높인다.
Nuxt 3는 동적 컴포넌트를 사용하면 필요할 때만 해당 컴포넌트를 로딩하는 방식으로 자동으로 코드 스플리팅을 수행합니다. 이로 인해 초기 로딩 속도가 향상되며, 불필요한 JS 코드의 다운로드를 방지할 수 있다.
Vue 3의 <keep-alive>는 동적 컴포넌트와 함께 사용되며, 컴포넌트 상태를 메모리에 보존하여 불필요한 렌더링을 방지한다. 이로 인해 성능 최적화는 물론, 사용자 경험 측면에서도 이점을 가질 수 있다.
예를 들어, 탭 전환 기능이 있는 UI에서 각 탭의 컴포넌트를 캐싱하면 탭을 다시 클릭했을 때 이전 상태를 그대로 유지할 수 있다.
<template>
<div>
<!-- 탭 버튼들 -->
<button @click="currentTab = 'Tab1'">Tab 1</button>
<button @click="currentTab = 'Tab2'">Tab 2</button>
<button @click="currentTab = 'Tab3'">Tab 3</button>
<!-- 동적 컴포넌트 + keep-alive -->
<keep-alive>
<component :is="currentTabComponent" />
</keep-alive>
</div>
</template>
<script setup>
import { ref, computed } from 'vue'
import Tab1 from '@/components/Tab1.vue'
import Tab2 from '@/components/Tab2.vue'
import Tab3 from '@/components/Tab3.vue'
const currentTab = ref('Tab1')
const currentTabComponent = computed(() => {
return {
Tab1,
Tab2,
Tab3
}[currentTab.value]
})
</script>
성능 최적화: 컴포넌트가 메모리에 유지되어 재렌더링을 방지하므로, 애플리케이션의 성능 향상
상태 보존: 컴포넌트가 다시 활성화될 때 이전 상태를 유지하여, 사용자 경험을 개선
전환 간 데이터 유지: 탭 전환이나 화면 간 이동 시, 컴포넌트의 데이터가 손실되지 않도록 할 수 있음
keep-alive는 캐싱할 컴포넌트를 제어할 수 있는 몇 가지 속성을 제공한다.
(vue3 공식문서 참고: https://ko.vuejs.org/guide/built-ins/keep-alive)
예를 들어 특정 컴포넌트만 캐싱하고 싶다면 include 속성을 사용할 수 있다.
<template>
/**
include: ['ComponentA', 'ComponentB'] - ComponentA와 ComponentB만 캐싱
exclude: ['ComponentC'] - ComponentC는 캐싱되지 않음
max: 2 - 최대 2개의 컴포넌트만 캐싱, 이 경우 ComponentA와 ComponentB가 캐싱
*/
<keep-alive :include="['ComponentA', 'ComponentB']" :exclude="['ComponentC']" :max="2">
<component :is="currentComponent" />
</keep-alive>
</template>
<script setup>
import { ref } from 'vue'
const currentComponent = ref('ComponentA')
</script>
이 기능을 활용하면 탭 전환이나 모달 등 상태를 보존하고 싶은 컴포넌트를 선택적으로 캐싱할 수 있어, 성능 개선과 사용자 경험 향상 모두에 기여할 수 있다.
현재 프로젝트에서는 다수의 모달 컴포넌트를 한 페이지에서 동적으로 처리하고 있어, 동적 컴포넌트의 도입이 적절하게 활용되고 있다.
다만, 동적 컴포넌트를 과도하게 사용하면 Vue의 가상 DOM 비교 과정이 복잡해져 성능에 악영향을 줄 수 있으며, 디버깅이 어려워질 가능성도 있기에 상황에 맞는 적절한 사용이 중요해보인다.
Nuxt 3는 다양한 최적화 기능을 제공하지만, 개발자의 선택과 적용 방식에 따라 성능 개선 효과의 차이가 클 수 있다. 동적 컴포넌트와 keep-alive는 Nuxt 3의 성능 최적화 전략 중 실무에서도 쉽게 적용 가능한 방법이니, 프로젝트에 맞게 적용해보길 권장한다!