Applied double-save rule: Master Archive + Specialized Mapping for Skybound, Datacollector, and Frontend Mastery.
8.3 KiB
단일 페이지 애플리케이션(SPA) 아키텍처 설계
📌 Brief Summary
단일 페이지 애플리케이션(SPA)은 서버로부터 최소한의 HTML 껍데기와 JavaScript 번들을 제공받은 후, 브라우저에서 동적으로 UI를 구성하고 렌더링하는 클라이언트 사이드 렌더링(CSR) 방식을 주로 활용하는 프론트엔드 아키텍처입니다 [1-4]. 초기 다운로드 크기가 커서 로딩이 느릴 수 있지만, 페이지가 로드된 이후에는 전체 페이지 새로고침 없이 부분적인 데이터만 업데이트하여 매끄럽고 상호작용성이 뛰어난 사용자 경험을 제공합니다 [5-8]. 현대의 SPA는 이러한 CSR의 단점을 극복하기 위해 서버 사이드 렌더링(SSR), 정적 사이트 생성(SSG), 그리고 컴포넌트 기반 아키텍처(CBA)와 같은 전략들을 혼합하여 성능과 확장성을 최적화합니다 [9, 10].
📖 Core Content
브라우저 렌더링 과정 (HTML → CSSOM → Render Tree)
브라우저의 중요 렌더링 경로(Critical Rendering Path)는 HTML을 점진적으로 파싱하여 DOM(Document Object Model) 트리를 구축하고, CSS를 파싱하여 렌더링 차단 리소스인 CSSOM(CSS Object Model)을 생성하는 것으로 시작됩니다 [11-14]. DOM과 CSSOM이 준비되면 이 둘을 결합하여 렌더 트리(Render Tree)를 형성합니다. 렌더 트리는 <script>나 display: none이 적용된 요소와 같이 화면에 보이지 않는 노드를 제외하고, 가시적인 노드와 그에 일치하는 계산된 스타일 정보만을 포함합니다 [15-18]. 이후 각 시각적 요소의 정확한 크기와 뷰포트 내 위치를 계산하는 레이아웃(Layout/Reflow) 단계를 거쳐, 픽셀을 화면에 그리는 페인트(Paint/Repaint)와 여러 레이어를 화면에 결합하는 합성(Compositing) 과정을 통해 UI가 표시됩니다 [19-23].
Reflow / Repaint 최소화 방법
Reflow(레이아웃)는 DOM 구조가 변경되거나 창 크기 조정, 마진, 너비, 높이 등의 기하학적 속성이 변경될 때 트리의 상당 부분을 다시 계산해야 하므로 컴퓨팅 자원을 크게 소모합니다 [24-27]. Repaint는 색상이나 그림자 등 시각적 스타일만 변경될 때 발생합니다 [24, 25, 27]. 성능 최적화를 위해서는 불필요한 DOM 트리의 깊이를 줄이고, CSS 규칙을 간소화하며, DOM 업데이트를 일괄 처리(batching)해야 합니다 [28-30]. 특히 애니메이션 요소는 top이나 left 대신 transform과 opacity 속성을 사용하여, 브라우저가 요소를 독립적인 레이어로 분리하고 GPU 가속(Compositing)을 활용하게 함으로써 Reflow를 피하는 것이 핵심입니다 [20, 29-31].
DOM vs Virtual DOM 및 React가 빠른 이유
전통적인 방식처럼 DOM을 직접 수정하면 레이아웃과 페인트 연산이 반복적으로 트리거되어 성능이 크게 저하됩니다 [32]. React는 이를 극복하기 위해 UI의 가벼운 메모리 내 표현인 가상 DOM(Virtual DOM)을 사용합니다 [32-34]. React는 컴포넌트의 상태가 변할 때마다 새로운 가상 DOM을 생성하고, 이전 상태와 비교하는 O(n) 복잡도의 휴리스틱 기반 Diffing 알고리즘(Reconciliation)을 실행하여 실제 변경된 속성이나 노드만 선별적으로 실제 DOM에 패치(업데이트)합니다 [32, 33, 35-37].
여기에 더해 React 16부터 도입된 파이버(Fiber) 아키텍처는 동시성 렌더링을 가능하게 합니다. 렌더링 작업을 중단, 재개, 혹은 폐기할 수 있는 작은 '작업 단위'로 분할하고, 사용자 입력이나 클릭과 같은 긴급한 작업을 데이터 필터링 같은 작업보다 우선 처리(우선순위 Lane 모델)하여 화면 버벅임(Jank)을 방지하고 반응성을 유지합니다 [38-44].
렌더링 최적화 개념 (자동 일괄 처리 및 React Compiler)
최신 React는 성능 병목을 프레임워크 단에서 해결하고 있습니다. React 18의 자동 일괄 처리(Automatic Batching)는 기존 이벤트 핸들러뿐 아니라 setTimeout이나 Promise 같은 비동기 작업에서 발생하는 다수의 상태 업데이트를 하나의 리렌더링으로 묶어 DOM 렌더링 횟수를 획기적으로 줄여줍니다 [45-48]. 더 나아가, React 19에 도입된 React Compiler는 빌드 단계에서 코드를 정적 분석하여 변경되지 않는 값과 컴포넌트에 메모이제이션을 자동 삽입합니다. 이로 인해 불필요한 재렌더링(Re-render Cascade)이 제거되고 개발자가 수동으로 useMemo, useCallback, React.memo를 작성해야 하는 인지적 부담이 사라집니다 [49-53].
CSR vs SSR vs SSG 렌더링 전략 비교
- CSR (Client-Side Rendering): 클라이언트(브라우저)에서 JavaScript를 실행해 전체 UI를 구축하고 데이터를 가져옵니다. 매우 동적인 상호작용을 지원하지만, 초기 렌더링까지 사용자가 빈 화면을 보게 되며 자바스크립트 실행이 필수적이라 검색 엔진 최적화(SEO)에 불리할 수 있습니다 [1, 2, 5, 54-57].
- SSR (Server-Side Rendering): 서버가 각 요청마다 데이터가 포함된 완전한 HTML을 렌더링하여 클라이언트에게 전송합니다. SEO에 매우 유리하며 초기 콘텐츠 페인트(FCP)가 빠르지만, 사용자 인터랙션을 위해 JavaScript 번들을 다운받고 연결하는 '하이드레이션(Hydration)' 과정 동안 입력 지연(TTI 지연)이 발생할 수 있습니다 [58-63].
- SSG (Static Site Generation) & ISR (Incremental Static Regeneration): 빌드 타임에 HTML을 생성하여 CDN으로 배포하는 방식으로 성능 면에서 가장 빠르나 잦은 데이터 변경에는 취약합니다(SSG). ISR은 이를 보완하여 주기적으로 정적 페이지를 백그라운드에서 재생성합니다 [64-70].
- React Server Components (RSC): 컴포넌트를 서버에서만 실행하고 직렬화된 데이터만을 클라이언트에 스트리밍하여 전송하는 혁신적 모델입니다. 클라이언트 자바스크립트 번들 크기에 전혀 영향을 주지 않고 서버 리소스(DB 등)에 직접 접근할 수 있게 해, 복잡한 프론트엔드 환경에서 상호작용이 필요한 클라이언트 컴포넌트(Client Component)와 역할을 명확히 분리합니다 [71-76].
컴포넌트 기반 아키텍처 (Component-Based Architecture) 최신의 단일 페이지 애플리케이션 설계는 시스템을 분리 가능하고 재사용 가능한 소프트웨어 조각(컴포넌트)으로 구성하는 CBA 방법론을 따릅니다 [77-79]. 각 컴포넌트는 특정한 상태와 UI 로직을 캡슐화(Encapsulation)하여 잘 정의된 인터페이스(Props 등)로 통신합니다 [77, 80]. 이 구조는 코드의 모듈성과 재사용성을 높이고 유지보수와 디버깅을 단순화하며, 여러 개발팀이 독립적으로 기능(예: 검색창, 장바구니 등)을 개발하여 빠르고 유연하게 확장할 수 있는 기반이 됩니다 [81-85].
🔗 Knowledge Connections
- Related Topics: 브라우저 렌더링 프로세스 (CRP), 가상 DOM (Virtual DOM) 및 재조정(Reconciliation), React Fiber 및 동시성 렌더링, 서버 사이드 렌더링(SSR)과 하이드레이션(Hydration), 컴포넌트 기반 아키텍처 (CBA)
- Projects/Contexts: Next.js를 활용한 하이브리드 렌더링 및 React Server Components 도입, React 18 자동 일괄 처리 및 React 19 컴파일러 최적화 적용
- Contradictions/Notes: CSR 방식은 초기 로드 속도와 SEO 측면에서 불리하다는 한계가 널리 알려져 있으나, 실시간 상호작용이 많고 SEO가 중요하지 않은 인증 기반의 SaaS 대시보드나 내부 비즈니스 도구에서는 서버의 렌더링 부하를 줄이고 유연성을 높이기 때문에 여전히 SSR보다 가장 적합한 렌더링 방식으로 권장됩니다 [4, 86, 87]. 또한, React 19 컴파일러가 대부분의 수동 메모이제이션을 불필요하게 만들지만, 외부 타사 라이브러리 연동 시 참조 안정성이 깨지거나 이펙트 의존성 제어가 필요한 특정 상황에서는 여전히
useMemo등을 통한 수동 제어가 필요할 수 있습니다 [88-90].
Last updated: 2026-04-25