zero-wiki Help

13장-렌더링-패턴

웹 사이트가 인터랙티브해짐에 따라, 처리해야 할 이벤트와 클라이언트에서 렌더링하는 콘텐츠의 양이 늘어났습니다. 그 결과, 리액트처럼 클라이언트에서 주로 렌더링되는 SPA가 등장하게 되었습니다.

렌더링 패턴은 주어진 사용 사례에 맞는 최적의 렌더링 방식을 제공합니다.

클라이언트 사이드 렌더링 (CSR)

HTML이 클라이언트에서 렌더링 됩니다.

서버 사이드 렌더링

서버에서 동적으로 HTML을 렌더링한 후, 클라이언트에서 하이드레이션 합니다.

정적 렌더링

빌드 타임에 서버에서 페이지를 렌더링하여 정적인 사이트를 구축합니다.

점진적 정적 생성 (ISR)

초기 빌드 이후에도 정적 사이트를 동적으로 추가하거나 수정할 수 있습니다.

스트리밍 SSR

서버에서 렌더링된 콘텐츠를 작은 스트림 조각으로 분할하여 전송합니다.

엣지 렌더링

렌더링된 HTML을 클라이언트에 전송하기 이전 엣지에서 수정합니다.

하이브리드 렌더링

빌드 타임, 서버 및 클라이언트 렌더링을 결합하여 웹 개발에 유연한 접근방식을 제공합니다.

부분 하이드레이션

일부 컴포넌트만 하이드레이션합니다.

점진적 하이드레이션

클라이언트에서 컴포넌트 하이드레이션 순서를 제어합니다.

아일랜드 아키텍처

정적인 사이트 내에 여러 진입점을 가진 동적인 동작의 격리된 영역을 만듭니다.

점진적 향상

자바스크립트 없이도 애플리케이션이 작동하도록 보장합니다.

13.1 렌더링 패턴의 중요성

주어진 상황에 가장 적합한 렌더링 패턴을 선택하는 것은 개발 경험과 최종 사용자를 위한 사용자 경험에 엄청난 차이를 만들 수 있습니다.

띄어난 사용자 경험을 제공하기 위해서는, 핵심 웹지표(CWV)와 같은 사용자 중심 지표를 기준으로 애플리케이션을 최적화해야 합니다.

  • TTFB: 클라이언트가 첫 번째 콘텐츠의 바이트를 받는데까지 걸리는 시간.

  • FCB: 페이지 이동후 콘텐츠의 첫 부분을 렌더링 하는데까지 걸리는 시간.

  • TTI: 페이지 로드 시작부터 사용자 입력에 응답할 수 있을 때까지 걸리는 시간.

  • LCP: 페이지의 주요 콘텐츠를 로드하고 렌더링하는 데 걸리는 시간.

  • CLS: 예상치 못한 레이아웃 변경을 방지하기 위한 시각적 안정성 측정.

  • FID: 사용자가 페이지아 상호작용한 시점부터 이벤트 핸들러가 실행될 수 있는 시점까지의 시간.

동시에 제품/엔지니어링 팀에게 훌륭한 개발 경험을 제공하기 위해서는 다양한 기능을 통해 개발 환경을 최적화 해야합니다.

  • 빠른 빌드 시간

  • 낮은 서버 비용

  • 동적 콘텐츠

  • 쉬운 롤백

  • 안정적인 가동 시간

  • 확장 가능한 인프라

이러한 원칙을 기반으로 개발 환경을 구축하면 훌륭한 제품을 효율적으로 만들 수 있습니다.

13.2 클라이언트 사이드 렌더링

CSR에서는 대부분의 애플리케이션 로직이 클라이언트에서 실행되며, 데이터를 가져오거나 저장하기 위한 API 호출로 서버와 상호작용 합니다.

따라서 거의 모든 UI가 클라이언트에서 생성되며, 전체 웹 애플리케이션은 처음 요청 시에 모두 로드됩니다.

또한 새로고침 없이 탐색을 지원하는 SPA를 구축할 수 있게 하여 뛰어난 사용자 경험을 제공합니다.

그러나 하나의 번들로 관리하기 때문에 페이지의 FCP, TTI와 같은 시간을 증가시킵니다. 또한 크롤러가 색인하기 이전 렌더링이 되지 않을수도 있기 때문에 SEO 성능에 영향을 끼칠수 있습니다.

13.3 서버 사이드 렌더링

SSR은 모든 요청마다 HTML을 생성합니다. 이 방식은 사용자 쿠키 정보나 요청 데이터를 기반으로 하는 등, 개인 맞춤형 데이터를 포함하는 페이지에 적합합니다.

SSR의 핵심 원칙은 HTML을 서버에서 렌더링하고 클라이언트에서 다시 하이드레이션하는데 필요한 자바스크립트를 함께 제공하는 것입니다.

13.4 정적 렌더링

정적 렌더링은 전체 페이지의 HTML을 빌드 시점에 미리 생성하며, 다음 빌드 때까지 변경되지 않습니다. 이 정적인 HTML 콘텐츠는 CDN이나 엣지 네트워크에 쉽게 캐싱될 수 있습니다. 웹 사이트의 '회사 소개', '문의 하기', '블로그'페이지와 같은 사이트들이 적합한 예시입니다.

13.4.1 점진적 정적 생성(ISR)

정적 렌더링과 SSR을 결합한 방식으로, 특정 정적 페이지만 미리 렌더링하고 동적 페이지는 사용자 요청 시에 on-demand 방식으로 렌더링 합니다.

이렇게 할 경우 빌드 시간이 단축되며, 특정 시간 간격마다 캐시를 자동으로 무효화하고 페이지를 다시 생성할 수 있습니다.

13.4.2 On-demand ISR

일반 ISR과 달리 특정 이벤트 발생 시에 페이지가 재생성됩니다.

일반 ISR에서는 업데이트된 페이지가 해당 페이지에 대한 사용자 요청을 처리한 엣지 네트워크 노드에만 캐시됩니다. 반면 On-demand ISR은 엣지 네트워크 전체에 페이지를 다시 생성하고 재분배하므로, 자동으로 전 세게 사용자가 캐시된 오래된 콘텐츠가 아닌 최신 버전의 페이지를 볼 수 있습니다.

13.4.3 정적 렌더링 요약

빌드 시점에 생성하는 정적인 웹 사이트에 매우 적합한 패턴입니다.

정적 렌더링은 항상 최선의 선택이 아닙니다. 사용자마다 동작이 다른 동적인 페이지의 경우 SSR이 이상적입니다.

13.5 스트리밍 SSR

SSR이나 정적 렌더링을 사용하면 자바스크립트의 용량이 줄어 상호작용 가능해지는 시간을 단축시킬 수 있습니다. 여기에 스트리밍 방식으로 콘텐츠를 전송하면 더욱 단축할 수 있습니다.

리액트에 내장된 renderToNodeStream 함수를 사용하면 애플리케이션을 작은 조각으로 나누어 전송할 수 있습니다. 클라이언트는 데이터를 받는 동시에 UI를 그리기 시작할 수 있습니다.

13.6 엣지 SSR

엣지 SSR은 CDN의 모든 지역에서 서버 렌더링을 가능하게 하고, 콜드 부트 시간을 0에 가깝게 줄여줍니다.

서버리스 함수를 사용하면 전체 페이지를 서버 사이드에서 생성할 수 있습니다.

사용자 별로 지역 특화 리스트 페이지를 구축하는 것이 사용 사례입니다.

13.7 하이브리드 렌더링

어떤 상황에서든 최적의 결과를 제공하기 위해 여러가지 렌더링 방식을 결합합니다.

정적으로 렌더링 될 수 있는 페이지는 미리 렌더링되고, 애플리케이션의 다른 페이지에는 동적인 전략을 선택할 수 있습니다.

13.8 점진적 하이드레이션

각 노드를 시간에 따라 개별적으로 하이드레이션하여 필요한 최소한의 자바스크립트만 요청하는 방식입니다.

상대적으로 덜 중요한 부분의 하이드레이션을 지연시켜 페이지를 상호작용할 수 있게 만드는 데 필요한 자바스크립트 양을 줄이고, 사용자에게 필요한 노드만 하이드레이션할 수 있습니다.

리액트의 lazysuspense와 같은 기능을 사용하여 선언적인 로딩 상태를 통해, 지연 로드되는 중임을 보여줄 수 있습니다.

13.9 아일랜드 아키텍처

아일랜드 아키텍처는 웹 페이지를 독립적인 "아일랜드"(섬)들로 구성하는 방식입니다. 각 아일랜드는 자체적으로 렌더링되고 상호작용할 수 있는 독립적인 컴포넌트입니다.

주요 특징:

  1. 독립성

    • 각 아일랜드는 독립적으로 작동

    • 자체 상태 관리와 라이프사이클을 가짐

    • 다른 아일랜드와 격리되어 있어 서로 영향을 주지 않음

  2. 점진적 하이드레이션

    • 각 아일랜드는 필요할 때만 하이드레이션됨

    • 초기 로딩 시간 단축

    • 사용자 경험 개선

  3. 마이크로 프론트엔드와의 차이점

    • 마이크로 프론트엔드는 전체 페이지를 독립적인 부분으로 나누는 반면

    • 아일랜드 아키텍처는 페이지 내의 특정 컴포넌트를 독립적으로 관리

  4. 장점

    • 성능 최적화

    • 코드 분할 용이

    • 유지보수성 향상

    • 점진적 개선 가능

  5. 구현 예시

// React에서의 구현 예시 const ProductIsland = lazy(() => import('./ProductIsland')); const CartIsland = lazy(() => import('./CartIsland')); function App() { return ( <div> <Suspense fallback={<LoadingSpinner />}> <ProductIsland /> </Suspense> <Suspense fallback={<LoadingSpinner />}> <CartIsland /> </Suspense> </div> ); }

이 아키텍처는 특히 대규모 웹 애플리케이션에서 성능과 유지보수성을 향상시키는 데 효과적입니다.

13.10 리액트 서버 컴포넌트

리액트 서버 컴포넌트(RSC)는 서버에서 실행되도록 설계된 상태를 가지지 않는 리액트 컴포넌트로, 서버 주도 방식으로 현대적인 사용자 경험을 제공하는 것을 목표로 합니다. 이러한 컴포넌트들은 번들 크기를 0으로 줄이고, 서버 컴포넌트와 클라이언트 컴포넌트 사이의 매끄러운 코드 전환 경험, 즉 니팅을 가능하게 합니다.

Last modified: 04 April 2025