Vue + SPA 아키텍처 가이드
아키텍처 그림 설명
[Vue Router]
|
v
[Page Shell]
|
+--+-------------------------+
| |
v v
[Feature Components] [Shared Layout]
| |
v v
[Pinia / Local State] [Navigation / Theme]
|
v
[API Client / Server State]
|
v
[Backend / BFF]
Vue SPA에서는 라우터가 단순 이동 도구가 아니라 화면 문맥의 뼈대가 됩니다. 그 위에 기능 컴포넌트가 올라가고, 상태는 전역 저장소와 로컬 상태로 나뉘며, 서버 데이터는 별도 규칙으로 관리됩니다. 이 층을 분리하지 않으면 컴포넌트가 화면, 상태, 네트워크를 모두 떠안게 됩니다.
Vue + SPA가 잘 맞는 제품
Vue SPA는 다음과 같은 조건에서 특히 강합니다.
- 로그인 이후 상호작용이 많은 백오피스
- 관리자 콘솔, 대시보드, 협업 도구
- 화면 전환이 빠르고 클라이언트 상태가 풍부한 제품
- 검색엔진 노출보다 사용자 작업 효율이 중요한 서비스
반대로 공개 콘텐츠 중심 사이트, SEO가 핵심인 미디어, 초기 로딩이 매우 중요한 랜딩 페이지는 SSR이나 SSG와 함께 비교하는 것이 좋습니다.
SPA 아키텍처에서 가장 중요한 것은 라우팅과 상태
Vue SPA는 결국 “현재 URL에 맞는 화면을 그리는 클라이언트 애플리케이션”입니다. 그래서 구조의 중심은 라우터와 상태 계층입니다.
- URL은 사용자 흐름과 화면 상태를 설명해야 한다
- 페이지 전용 상태와 전역 상태를 분리해야 한다
- 서버 데이터는 캐시 정책과 함께 관리해야 한다
- 페이지 간 이동 시 다시 불러와야 할 것과 유지해야 할 것을 나눠야 한다
이 기준이 없으면 SPA는 곧 거대한 브라우저 안의 모놀리식 앱이 됩니다.
Vue SPA에서 라우터는 앱의 골격이다
Vue Router는 페이지 전환 라이브러리가 아니라 앱 구조의 중심입니다. 대시보드, 상세, 편집, 설정처럼 사용자 흐름이 URL에서도 드러나야 히스토리, 즐겨찾기, 권한 제어, 복구 경험이 좋아집니다.
또한 중첩 라우트를 잘 쓰면 상위 레이아웃은 유지하고 하위 콘텐츠만 바꾸는 구조를 쉽게 만들 수 있습니다. 이 점은 SPA 경험을 부드럽게 만드는 데 중요합니다.
상태는 가능한 한 좁게 두는 것이 유리하다
Vue SPA가 무거워지는 대표 이유는 모든 상태를 전역으로 끌어올리기 때문입니다. 다음처럼 나누면 구조가 더 건강합니다.
- 로컬 상태: 폼 입력, 패널 열림, 일시적 선택값
- URL 상태: 검색 조건, 정렬, 페이지 번호
- 공유 상태: 인증, 사용자 설정, 공통 필터
- 서버 상태: 목록, 상세 데이터, 실시간 갱신 대상
특히 페이지 필터와 검색 조건은 URL과 함께 가야 사용자 경험과 공유 가능성이 좋아집니다.
서버 상태는 단순 fetch 이상으로 다뤄야 한다
SPA는 처음엔 클라이언트에서 데이터를 가져오면 끝처럼 보이지만, 실제 운영에서는 stale 데이터, 중복 요청, race condition, 낙관적 업데이트, 로딩 상태 일관성이 문제가 됩니다. 그래서 API 요청은 단순 유틸 함수가 아니라 캐시와 동기화 정책을 포함한 계층으로 보는 것이 좋습니다.
초기 로딩 비용은 SPA의 가장 큰 약점 중 하나다
SPA는 클라이언트 번들이 커질수록 첫 진입 경험이 나빠집니다. Vue 프로젝트에서는 특히 다음을 주의해야 합니다.
- 라우트 단위 코드 분할
- 무거운 차트/에디터 라이브러리 지연 로딩
- 공통 번들에 너무 많은 기능 포함 금지
- 이미지와 폰트 최적화
- 초기 렌더 이전 필수 데이터 최소화
SPA는 화면 전환이 빠른 대신 첫 진입 비용을 어떻게 줄일지가 핵심입니다.
인증과 권한은 라우터와 함께 설계한다
Vue SPA는 로그인 이후 화면이 많은 경우가 많기 때문에, 인증과 권한 처리를 컴포넌트마다 흩뿌리기보다 라우터와 레이아웃 경계에서 먼저 정리하는 편이 좋습니다. 예를 들어 인증이 필요한 구역과 공개 구역을 라우터 수준에서 나누면 전체 구조가 더 읽기 쉬워집니다.
운영 관점에서 SPA가 흔히 겪는 문제
실무에서는 다음 문제가 자주 발생합니다.
- 새로고침 시 특정 경로에서 404가 난다
- 브라우저 히스토리와 내부 상태가 어긋난다
- 전역 상태가 오래 남아 잘못된 화면이 보인다
- 큰 번들 때문에 초기 진입이 느리다
- 에러 경계 없이 화면 전체가 깨진다
이 문제들은 대부분 배포 설정, 라우팅 설계, 상태 범위, 에러 처리 전략과 연결되어 있습니다.
Vue SPA를 오래 유지하려면 필요한 기준
- URL 상태를 의도적으로 설계한다
- 전역 상태는 최소화한다
- API 계층을 분리한다
- 페이지 전환과 초기 로딩을 다르게 최적화한다
- 에러, 로딩, 빈 상태를 디자인한다
SPA는 단순히 페이지가 안 새로고침되는 앱이 아니라, 브라우저 안에서 오래 살아남아야 하는 애플리케이션입니다.
마무리
Vue + SPA의 핵심은 빠르게 만드는 것이 아니라, 브라우저 안에서 지속적으로 안정적으로 동작하는 구조를 만드는 것입니다. 라우터, 상태, 캐시, 코드 분할, 배포 설정이 함께 맞물릴 때 SPA는 부드러운 사용자 경험과 높은 생산성을 동시에 줄 수 있습니다.
운영 환경에서 어려워지는 지점
- Vue SPA에서는 SPA에서는 navigation, 데이터 패칭, 권한, 레이아웃 유지가 각자 따로 진화하면 아키텍처가 급격히 어려워진다.
- 브라우저 세션이 길어질수록 메모리 누수, stale cache, 암묵적 전역 상태가 생각보다 빨리 드러난다.
- SPA 모델은 여전히 유효하지만 페이지 생애주기를 화면 모음이 아니라 하나의 시스템으로 다뤄야 한다.
중요한 아키텍처 결정
- Vue Router와 명시적인 화면 경계를 중심으로 route 소유권을 설계한다.
- route 전환 사이에서 서버 데이터가 어떻게 캐시되고 무효화되고 새로고침되는지 정의한다.
- 애플리케이션 shell, feature 모듈, 공용 도메인 로직을 분리한다.
실무 예시
신뢰할 수 있는 SPA는 대개 shell, feature route, 데이터 접근 책임을 분리한다.
app shell
-> route modules
-> screen containers
-> presentational components
-> 공용 query 계층
-> 공용 auth/session 계층
피해야 할 안티패턴
- route 컴포넌트가 공통 정책 없이 모든 것을 제각각 fetch하는 것.
- navigation 사이에서 너무 많은 일시 상태를 계속 살려두는 것.
- feature 소유권 없는 거대한
src/pages디렉터리를 키우는 것.
운영 체크리스트
- route별 번들 크기와 전환 지연을 검토한다.
- stale cache와 중복 요청 패턴을 추적한다.
- 핵심 워크플로우에서 브라우저 navigation과 reload 동작을 테스트한다.
- 긴 세션 동안 메모리 증가를 측정한다.
최종 판단
Vue SPA에서는 SPA는 상호작용이 많은 제품에 여전히 강한 선택이지만, route 전환, 상태 소유권, 캐시 정책을 의도적으로 설계할 때만 그렇다.
Continue Reading
다음으로 읽기 좋은 글
Vue.js 아키텍처 설계 가이드
Vue.js 프로젝트를 단순 컴포넌트 모음이 아니라 유지보수 가능한 프런트엔드 시스템으로 설계하는 방법을 정리합니다. 상태 경계, 라우팅, 데이터 흐름, 폴더 구조, 성능과 협업 관점까지 실무 중심으로 다룹니다.
🖥️ FrontendReact + SPA 아키텍처 가이드
React 기반 SPA를 설계할 때 필요한 화면 경계, 상태 구조, 라우팅, 데이터 계층, 성능 전략을 실무 관점에서 정리합니다.
⚙️ BackendCQRS + Event Sourcing 실전 구현 가이드
CQRS와 Event Sourcing을 도메인 경계와 운영 복잡성의 관점에서 설명하고, Aggregate, Event Store, Projection, Snapshot, 정합성 모델의 선택 기준을 정리합니다.
💬 LanguageI/O 경계에서의 타입 좁히기 전략
언어의 타입 시스템은 경계 안에서 강하지만, 외부 입력 앞에서는 다시 확인이 필요합니다. I/O 경계에서 타입을 좁히는 전략을 정리합니다.
다음 탐색