2 분 소요

들어가며

웹 애플리케이션의 규모가 커질수록 성능 최적화는 선택이 아닌 필수가 됩니다. 사용자 경험(UX)은 페이지 로딩 속도와 부드러운 인터랙션에 직접적으로 연결되기 때문입니다. Vue.js는 기본적으로 뛰어난 성능을 제공하지만, 복잡한 데이터 구조나 대규모 리스트를 다룰 때는 개발자가 직접 최적화에 신경 써야 합니다.

이번 포스트에서는 Vue.js 애플리케이션의 성능을 측정하는 방법부터, 실무에서 즉시 적용 가능한 주요 최적화 방법들을 살펴봅니다.

성능 모니터링 도구

최적화 작업을 할 때 언제나 그렇듯이 시작은 현재 상태를 정확히 진단하는 것입니다. 상태를 점검하는 데는 아래와 같은 도구를 활용할 수 있습니다.

1. Vue Devtools (Performance Tab)

Vue 전용 브라우저 확장 프로그램인 Vue Devtools는 컴포넌트의 렌더링 시간을 시각적으로 보여줍니다.

Vue DevTools의 대시보드 화면. 프로젝트의 전반적인 상태를 한눈에 확인할 수 있습니다.

Vue DevTools 대시보드

  • Timeline: 컴포넌트의 마운트, 업데이트, 언마운트 시점을 추적합니다.
  • Performance: 각 컴포넌트가 렌더링되는 데 걸리는 시간을 밀리초(ms) 단위로 측정하여 병목 지점을 찾을 수 있습니다.

2. Chrome DevTools (Lighthouse & Performance)

Lighthouse를 통해 Web Vitals(LCP, FID, CLS) 지표를 확인하고, Performance 탭에서 메인 스레드의 작업 부하를 분석할 수 있습니다.

3. Sentry (Error & Performance Monitoring)

실제 운영 환경에서의 성능 데이터를 수집하고 싶다면 Sentry와 같은 도구를 활용합니다. 사용자가 겪는 실제 지연 시간을 트랜잭션 단위로 추적할 수 있습니다. 1

주요 최적화 방법

1. v-memo를 이용한 템플릿 메모이제이션 (Vue 3.2+)

v-memo는 템플릿의 특정 부분을 메모이제이션하여, 지정한 값이 변경되지 않았을 때 재렌더링을 건너뛰게 합니다. 대규모 리스트에서 특정 아이템만 업데이트해야 할 때 유용합니다.

<!-- v-memo 활용 예시 -->
<div v-for="item in list" :key="item.id" v-memo="[item.id === selectedId]">
  <p> - </p>
  <!-- selectedId가 현재 item.id와 일치하는 상태가 변할 때만 이 부분이 업데이트됩니다. -->
</div>

2. shallowRefshallowReactive 활용

Vue의 기본 ref는 객체의 모든 깊이까지 반응성을 부여합니다. 하지만 대량의 데이터를 단순히 표시만 하거나 외부 라이브러리 인스턴스를 저장할 때는 이런 깊은 반응성이 오버헤드가 될 수 있습니다.

import { shallowRef } from 'vue'

// ✅ 올바른 예시: 대규모 데이터 구조에 shallowRef 사용
const bigData = shallowRef({ 
  /* 수만 개의 프로퍼티가 있는 객체 */ 
})

// .value 전체를 교체할 때만 반응성이 트리거됩니다.
bigData.value = { new: 'data' }

// ❌ 잘못된 예시: 내부 속성 변경은 감지되지 않음
bigData.value.someProperty = 'change' 

3. 비동기 컴포넌트 (Async Components)

defineAsyncComponent를 사용하면 컴포넌트를 필요할 때만 로드하여 초기 번들 크기를 줄일 수 있습니다. 단, 모든 컴포넌트에 과도하게 적용할 경우 개별 리소스 로딩 순서 차이로 인해 레이아웃 시프트(CLS)가 발생할 수 있으므로, 핵심 UI 요소는 즉시 로딩하는 것이 유리할 수 있습니다.2

import { defineAsyncComponent } from 'vue'

// 비동기 컴포넌트 정의
const AsyncModal = defineAsyncComponent(() =>
  import('./components/LargeModal.vue')
)

4. v-once로 정적 콘텐츠 최적화

한 번 렌더링된 후 절대 변하지 않는 콘텐츠에는 v-once를 적용합니다. Vue.js는 이 엘리먼트를 이후 업데이트 프로세스에서 완전히 제외합니다.

<div v-once>
  <h1>서비스 이용 약관</h1>
  <p>이 내용은 페이지가 로드된 후 절대 변경되지 않습니다.</p>
</div>

5. 이미지 및 리소스 최적화

  • 이미지 레이지 로딩: IntersectionObserver를 활용하여 사용자의 화면에 보이는 시점에 이미지를 로드합니다. Vue에서는 커스텀 디렉티브(Custom Directive)를 만들어 재사용 가능하게 구현할 수 있습니다.
  • 이미지 압축: imagemin이나 pngquant 등을 활용하여 품질 저하를 최소화하면서 용량을 줄입니다. 카카오 비즈니스폼 사례에 따르면 75-100% 품질 범위 내의 손실 압축은 시각적 차이가 거의 없으면서도 큰 용량 절감 효과를 제공하는 것으로 볼 수 있습니다.2
  • CSS 최적화: CSS를 JavaScript 번들에서 분리(Extraction)하고, PurgeCSS와 같은 도구로 사용하지 않는 스타일을 제거하여 초기 로딩 속도를 개선합니다.

마무리

Vue.js 애플리케이션 성능 최적화의 핵심은 다음과 같습니다.

  1. 측정: Vue Devtools와 Lighthouse로 병목 지점을 찾습니다.
  2. 반응성 최적화: 대규모 데이터에는 shallowRef를, 템플릿에는 v-memo를 고려합니다.
  3. 코드 스플리팅 및 로딩 제어: 비동기 컴포넌트로 번들 크기를 줄이되, 레이아웃 안정성을 위해 로딩 우선순위를 관리합니다.
  4. 리소스 최적화: 이미지 압축, 레이지 로딩, CSS 최적화를 통해 네트워크 병목을 해소합니다.

참고 자료:


참고 자료:

  1. Sentry Performance Monitoring - 실시간 성능 모니터링 가이드 

  2. Kakao Tech - FE 성능개선기 2부: 카카오 비즈니스폼 - 실무 프론트엔드 성능 개선 사례 및 트러블슈팅  2

카테고리:

업데이트:

댓글남기기