Skip to main content

Command Palette

Search for a command to run...

Modern React Deep Dive: 서버 사이드 렌더링

Updated
•2 min read•View as Markdown
Modern React Deep Dive: 서버 사이드 렌더링
J

Interested in fundamental of web develop

서버 사이드 렌더링

서버 사이드 렌더링(SSR)이란 웹 애플리케이션의 컨텐츠를 서버에서 렌더링하는 기법을 말한다.

SSR에 대해 알아보기 전에 기존의 프론트엔드 중심 개발 방법 중 하나인 싱글 페이지 애플리케이션(SPA)를 알아본다.

싱글 페이지 애플리케이션(SPA)

과거엔 자바스크립트로 할 수 있는 일이 제한적이라 대부분의 처리를 서버에서 해야 했다. (데이터 연동, 페이지 렌더링, 인증/인가 로직 등)
그 구조로 인해 관심사의 분리가 덜 이루어져 애플리케이션 확장, 서버 유지보수에 어려움을 가져왔었다.

자바스크립트의 진화와 REST API, AJAX와 같은 개념의 등장으로 클라이언트 사이드에서 많은 일을 할 수 있게 되었다.
이를 통해 전체 페이지를 다시 요청하여 렌더링하지 않고, 클라이언트 사이드에서 라우팅하며 필요한 데이터만 서버에 요청하여 DOM만을 변경하는 SPA(CSR) 패러다임이 등장했다.

다시 떠오르는 서버 사이드 렌더링

CSR의 태생적인 한계 때문에 SSR이 다시 떠오르는 중이다.

모던 프론트엔드 개발에서 SSR을 도입함으로 얻어지는 장점

  • 최초 페이지 진입이 빠르다.

  • SEO에 유리하다.

  • 렌더링을 서버에서 수행하므로 디바이스 성능을 덜 고려해도 된다.

SSR과 CSR을 선택할 때 고려해봐야할 점

  • CSR을 아주 적절히 활용하면 훌륭한 애플리케이션을 만들 수 있다.(ex: GMail)

  • 평균적인 CSR 애플리케이션은 평균적인 SSR 애플리케이션 보다 느리다.

  • CSR은 SEO가 어렵다.

  • SSR은 서버 부하 또한 생각해야 한다.

따라서 어느 하나가 우월한 것이 아니라 상황에 따라 적절한 선택을 내려야 한다.


리액트에서 제공하는 SSR API

renderToString

인자로 넘겨받은 리액트 컴포넌트를 렌더링해 HTML 문자열로 반환하는 함수다.

리액트 훅과 이벤트 핸들러 등의 요소는 포함되지 않는다.

renderToStaticMarkup

renderToString과 매우 유사하나, 리액트에서만 사용하는 추가적인 DOM 속성을 만들지 않고 순수한 HTML 문자열만 반환한다.

renderToNodeStream

renderToString과 결과물이 완전히 동일하지만 결과물의 타입이 Node.js의 ReadableStream이라 브라우저에서 사용이 불가하다. (Node.js에 의존됨)

ReadableStream 객체로 나오는 이유는 큰 크기의 데이터를 청크 단위로 분리해 순차적으로 처리하기 위함이다.

renderToStaticNodeStream

renderToStaticMarkup과 동일하지만 renderToNodeStream처럼 결과물의 타입이 ReadableStream이다.

hydrate

renderToString과 renderToNodeStream으로 생성된 HTML 콘텐츠에 자바스크립트 핸들러, 이벤트를 붙이는 메소드이다.

서버에서 제공해 준 HTML과 클라이언트가 렌더링한 결과물이 같을 것으로 예상하고 동작한다.
결과물이 다를 경우 새로 hydrate가 렌더링한 기준으로 웹페이지를 그리게 된다.
불가피하게 불일치가 발생할 경우 해당 요소에 suppressHydrationWarning을 추가해 경고를 끌 수 있다.


Next.js

Next.js는 Vercel에서 만든 리액트 기반 프레임워크다.
최근에는 React 팀에서도 리액트 개발을 새로 시작할 때엔 Next.js와 같은 프레임워크 사용을 추천한다.

최초 요청 시엔 SSR을 수행하거나 SSG로 생성된 페이지를 돌려주지만 이후 라우팅은 클라이언트 사이드 라우팅을 수행한다.

Next.js를 도입함으로 얻는 이점은 다음과 같다.

  • 파일 기반 라우팅: App Router(13.4 버전에서 정식 릴리즈), Page Router(기존 방식)와 같은 방식으로 자동으로 라우트를 생성한다.

  • 자동 정적 최적화: SSR이 필요한지 자동으로 판단하고 필요하지 않은 페이지 컴포넌트는 자동으로 SSG로 생성해준다.

  • API 라우트: 간단하게 API 엔드포인트를 생성하여 백엔드 로직을 애플리케이션에 쉽게 통합할 수 있게 해준다.

  • 이미지 최적화: next/image를 통해 자동으로 이미지를 최적화하고 성능을 개선할 수 있게 해준다.

  • 코드 스플리팅: 자동으로 필요한 코드 스플리팅을 수행하고 링크된 페이지를 프리페치하는 기능이 있다.

More from this blog

Vanilla SPA 1: JSX & Virtual DOM Diffing

대망의 나만의 리액트 스타일 SPA 만들기 시작해보겠습니다. 이번 아티클에서는 JSX 파싱 JSX to Virtual DOM Virtual DOM Diffing Commit 을 다뤄보도록 하겠습니다. JSX란? JSX란 XML 스타일의 트리 구조로 표현하고 싶은 것들을 자바스크립트와 함께 작성하는 문법입니다. JSX의 구성 요소 JSXElement: HTML element와 비슷한 역할을 하는 컴포넌트 JSXAttributes: ...

Feb 23, 20245 min read
Vanilla SPA 1: JSX & Virtual DOM Diffing

Typescript: unknown과 any의 차이

타입스크립트의 타입 시스템을 공부하다 문득 unknown도 모든 타입 다 들어가고 any도 다 들어가는데 뭐가 다른거지? 라는 생각이 들어서 무슨 차이가 있는지 찾아보았다. unknown 사용시(프로퍼티에 접근 시, 연산 시) 타입을 지정해주어야 함 다른 타입에 할당 불가능 타입의 가능성을 열어뒀다가 좁히는 용도로 사용 any 나는 타입이길 포기한다

Jan 23, 20241 min read
Typescript: unknown과 any의 차이

모든 웹 개발자가 관심을 가져야 할 핵심 웹 지표

Core Web Vitals 구글에서 만든 것으로 웹페이지의 성능을 평가하는 지표들. LCP Largest Contentful Paint 페이지 로딩 성능을 의미하는 것. 의미 정확히는 '페이지가 처음으로 로드를 시작한 시점부터 뷰포트 내부에서 가장 큰 이미지 또는 텍스트를 렌더링하는 데 걸리는 시간' 뷰포트란?사용자에게 현재 노출되는 화면. 기기마다 다르다. '큰 이미지와 텍스트'는 아래의 요소들을 뜻한다. <img> <svg> 내부의...

Jan 5, 20242 min read
모든 웹 개발자가 관심을 가져야 할 핵심 웹 지표

Modern React Deep Dive: 리액트 17, 18 변경사항

현재 인터넷에서 가장 많이 쓰이는 리액트 버전은 16 버전이다. 그 이후 버전인 17, 18 버전에서 어떠한 변화가 있었는지 살펴보자. 리액트 17 버전 리액트 17 버전은 새롭게 추가된 기능이 없으며 기존 코드의 수정을 필요로 하는 변경 사항이 최소화되어있다. 이전 버전과의 호환성을 중시하며 17 버전으로 이동하기 쉽도록 만들어져 있다. 이벤트 위임 방식 변경 이전 버전에서는 이벤트 핸들러가 문서의 루트(Document)에서 이벤트를 캐치했지...

Dec 31, 20234 min read
Modern React Deep Dive: 리액트 17, 18 변경사항

얼렁뚱땅 알잘딱깔센 개발 라이프🙌

9 posts

문의는 DM으로 부탁드려요🙏