CSR, SSR, SSG와 Next.js

xxziiko·2024년 12월 18일

[Next.js]

목록 보기
1/2
post-thumbnail

CSR, SSR, SSG란 무엇인가?

CSR (Client Side Rendering)

  • 클라이언트(브라우저) 측에서 화면을 렌더링하는 방식
  • 초기 요청 시 정적 웹 서버가 최소한의 HTML과 JavaScript 파일만 전달
  • 브라우저가 JavaScript를 실행해 필요한 데이터를 요청하여 화면을 렌더링

CSR이 등장한 배경?

  • 전통적인 서버 중심의 렌더링 방식(SSR)은 페이지 전환 시마다 전체 HTML을 새로 받아와 매번 렌더링
  • 이 때문에 페이지 전환 마다 매번 네트워크를 요청 발생
    👉 서버 부하 증가 👉 네트워크 비용 증가 👉 사용자 경험 저하

CSR이 개선한 것은?

  • 매번 전체 HTML을 받아오지 않고 초기 로딩 이후에 Javascript를 사용해 필요한 데이터만 가져와 화면을 동적 업데이트(SPA)
  • 이로 인해 빠른 페이지 전환이 가능해졌고, 사용자를 기다리지 않게 한다. (사용자 경험 개선)

🧐 SPA (Single Page Application) ?

단일 HTML 페이지를 기반으로 동작하며, 페이지 전환 시 전체 페이지를 다시 로드하지 않고 클라이언트 측에서 동적으로 콘텐츠를 업데이트하는 웹 애플리케이션을 의미.
SPA는 React, Vue, Angular와 같은 JavaScript 라이브러리와 프레임워크를 통해 구현되며, 빠른 페이지 전환과 부드러운 사용자 경험을 제공하는 것이 특징이다.

단점

  • 초기 로딩이 느리다. 초기에 데이터를 한 번에 불러와야 하기 때문에 초기 렌더링이 느리다.
  • 초기 HTML이 빈 상태로 제공될 수 있어 검색 엔진 최적화(SEO)에 불리하다.
  • JavaScript 의존성이 높다.


SSR (Server Side Rendering)

  • 서버에서 HTML을 생성하여 브라우저에 전달하는 방식
  • 유저가 페이지를 요청할 때마다 HTML 문서가 생성

SSR은 어떤 문제점을 해결?

  • CSR은 초기 로딩 속도가 느리기 때문에 SEO에 불리
  • 초기 요청 시 서버에서 HTML을 렌더링하여 클라이언트에 전달하므로 빠른 초기 로딩과 SEO 최적화가 가능
  • 사용자의 요청이 있을 때 마다 동적으로 페이지를 생성하기 때문에 데이터가 자주 변경되는 페이지에 적합하다 (분석 차트, 실시간 금융 데이터)

단점

  • 매 요청마다 서버에서 HTML을 생성하므로 서버 부하가 증가
  • 클라이언트에서 추가적인 JavaScript 실행이 필요 (Hydration)

🧐 Hydration

서버에서 미리 생성된 HTML에 클라이언트가 JavaScript를 적용해 인터랙티브(동적)한 기능을 활성화하는 과정

👉 브라우저가 서버에서 전달받은 HTML을 화면에 렌더링 후, JavaScript를 다운로드하고 실행하는 과정에서 JavaScript 로직을 연결하여 상호작용이 가능하도록 만드는 과정을 Hydration이라고 한다.



SSG (Static Site Generation)

  • 빌드 타임에 HTML을 생성하여 정적 파일로 제공하는 방식
  • 브라우저 요청 시 서버에서 이미 생성된 HTML을 반환한다.

SSG는 어떤 문제점을 해결?

  • SSR이 초기 로딩 속도와 SEO 최적화를 개선했지만 매 요청 마다 서버에서 HTML을 생성하는 것은 트래픽이 많은 서비스에서는 부담
  • SSG를 통해 정적 파일을 제공함으로써 서버 부하 문제를 개선, 글로벌 CDN을 활용하여 초고속 로딩과 SEO 최적화를 가능하게 한다.
  • 변경이 적은 정적 콘텐츠에 유리하다 (블로그, 문서 페이지, 회사 소개 웹페이지 등)

단점

  • 데이터가 자주 변경되면 빌드와 배포를 반복해야 한다.
  • 실시간 데이터 반영의 어려움 (ISR로 일부 해결 가능)
  • 페이지 수가 많을 경우 빌드 시간이 증가할 수 있다.

🧐 CDN?

CDN(Content Delivery Network)은 전 세계에 분산된 서버 네트워크를 통해 사용자에게 콘텐츠(HTML, CSS, JavaScript, 이미지, 비디오 등)를 빠르고 효율적으로 제공하는 시스템



CSR, SSR, SSG 요약

  • CSR 👉 클라이언트에서 렌더링하며, 사용자 상호작용이 많은 애플리케이션에 적합.
  • SSR 👉 서버에서 HTML을 생성하여 SEO가 중요하거나 최신 데이터가 필요한 페이지에 적합.
  • SSG 👉 빌드 타임에 정적 파일을 생성해 성능 최적화가 필요한 정적 콘텐츠에 적합.


React에서의 CSR, SSR, SSG

  • React는 기본적으로 CSR(Client-Side Rendering)을 중심으로 설계된 Javascript 라이브러리
  • React에서도 SSR을 구현하기 위한 ReactDOMServer를 제공한다.(renderToString, renderToStaticMarkup 등).
  • 다만, 데이터 패칭, SEO, 라우팅 관리를 수작업으로 처리해야 하기 때문에 복잡성이 늘어난다.

ReactDOMServer로 SSR을 구현한다면?

  • ReactDOMServer는 React에서 서버 사이드 렌더링(SSR)을 구현하기 위해 제공되는 API로, React 컴포넌트를 서버에서 HTML 문자열로 변환하여 클라이언트에 전달
  • React 자체에서 SSR을 구현할 수 있지만, 이를 직접 구현하려면 여러 가지 복잡한 작업을 처리해야 한다.

ReactDOMServer를 사용한 SSR의 동작 방식

1. HTML 생성 : ReactDOMServer의 renderToString 또는 renderToStaticMarkup 메서드를 사용하여 React 컴포넌트를 HTML 문자열로 변환
2. 클라이언트로 전달 : 서버에서 생성된 HTML을 클라이언트에 전달하여 초기 화면을 렌더링
3. 클라이언트 하이드레이션 : 클라이언트에서 JavaScript가 로드되면, React는 서버에서 생성된 HTML을 하이드레이션하여 상호작용 가능한 애플리케이션으로 활성화

import express from 'express';
import React from 'react';
import ReactDOMServer from 'react-dom/server';
import App from './App.js'; // React 애플리케이션의 루트 컴포넌트

const server = express();

// 정적 파일 서빙
server.use('/static', express.static('public'));

// SSR 처리
server.get('*', (req, res) => {
  // React 컴포넌트를 HTML로 변환
  const appHTML = ReactDOMServer.renderToString(<App />);
  
  // HTML 페이지 반환
  const html = `
    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>SSR Example</title>
        <link rel="stylesheet" href="/static/styles.css">
      </head>
      <body>
        <div id="root">${appHTML}</div>
        <script src="/static/bundle.js"></script>
      </body>
    </html>
  `;
  res.send(html);
});

// 서버 실행
const PORT = 3000;
server.listen(PORT, () => {
  console.log(`SSR server running at http://localhost:${PORT}`);
});

👉 서버 설정, 데이터 패칭 로직, 라우팅 관리와 같은 보일러 플레이트 코드가 증가하여 코드가 복잡해진다.

🧐 이를 해결하고 React에서도 편하게 SSR/SSG를 사용할 수는 없을까?



Next.js

Next.js는 SSR, SSG, CSR을 유연하게 지원하여 개발자경험(DX)를 향상 시킨 React 기반의 프레임워크이다. React로 SSR/SSG를 구현할 때 발생하는 복잡한 작업을 간소화하고, 효율적인 데이터 패칭, SEO 최적화, 정적 사이트 생성 등을 손쉽게 구현할 수 있도록 설계되어있다.

React의 단점을 보완

  • React는 기본적으로 CSR(Client-Side Rendering)을 중심으로 설계된 라이브러리이기 때문에 SSR/SSG 방식을 적용하려면 수동으로 로직을 작성하고 개발자가 해당 코드를 관리해야하는 리소스 발생, SEO 취약점 등의 단점이 존재
  • Next.js는 CSR, SSR, SSG, ISR, RSC(Server Components) 등 다양한 렌더링 방식을 제공
  • Next.js에서는 단일 렌더링 방식으로 모든 문제를 해결할 수 없기 때문에 컴포넌트 별로 적절한 렌더링 방식을 결합하여 유연하고 효율적인 애플리케이션을 설계하는 것을 지향한다.


Next.js의 렌더링 방식

HTML을 어떤 시점에 생성하냐에 따라 정적/동적으로 나눈다.

  • 빌드 타임에 HTML 생성 👉 정적
  • 요청 시점에 HTML 생성 👉 동적

1. 정적 렌더링

  • SSG, ISR

SSG

🧐 ISR (Incremental Static Regeneration) ?

Next.js에서 SSG(Static Site Generation)를 기반으로, 정적 사이트의 HTML을 빌드 이후에도 동적으로 업데이트할 수 있는 기능

  • 초기에는 정적으로 렌더링된 HTML을 제공하여 빠른 로딩 속도를 유지하면서도, 특정 주기마다 데이터를 갱신하여 최신 콘텐츠를 제공
  • 정적 사이트의 성능과 서버 기반 렌더링의 유연성을 결합한 방식

ISR은 어떤 문제점을 해결했는가?

  • SSG의 비유연성을 개선
    SSG는 빌드 타임에만 데이터를 가져와 HTML을 생성하므로, 빌드 이후 콘텐츠 변경사항이 반영되지 않는 단점이 존재하는데, 이는 자주 업데이트되는 데이터를 가진 애플리케이션에서 빌드마다 새롭게 배포해야 하는 불편함이 발생된다. 정적 렌더링의 장점을 가져가면서도 빌드 이후에도 주기적으로 최신 콘텐츠를 반영하기 위해 ISR를 사용한다.

  • 빌드 시간의 증가
    SSG로 대규모 페이지를 생성할 경우, 빌드 시 모든 페이지를 한번에 생성해야 하므로 빌드 시간이 매우 길어질 수 있다. 이를 필요한 페이지만 백그라운드에서 업데이트 하는 방식으로 개선하여 서버 부하를 최소화하고 성능을 유지한다.

ISR 동작 원리

  1. 빌드 타임에 초기 HTML 생성
  2. 재생성 주기(revalidate) 설정
  3. 페이지 요청 시 기존 HTML 반환, revalidate 주기가 지나면 서버는 백그라운드에서 새로운 HTML 생성하고 새로운 HTML은 그 다음 요청부터 제공한다.

비동기로 데이터를 갱신하기 때문에 새 데이터를 가져오는 동안에도 기존 HTML이 사용되어 사용자 경험에 영향을 미치지 않는다 !

2. 동적 렌더링

  • SSR, CSR

3. React Server Component (RSC)

  • React의 새로운 기능으로, 클라이언트에서 실행되지 않고 서버에서만 실행되는 컴포넌트
  • 클라이언트 번들 크기를 줄여 성능을 더 최적화 할 수 있다.
  • 데이터 패칭과 같은 작업을 서버에서 처리할 수 있다.
  • Next.js에서는 Server Components와 Client Components를 조합하여 혼합 렌더링이 가능하다.


Next.js 렌더링 패턴

Server Components와 Client Components의 조합

  • Server Components는 서버에서 실행되며 데이터 패칭, 비밀 데이터 처리, HTML 생성과 같은 작업에 적합하다.
  • Client Components는 브라우저에서 실행되며 사용자와의 상호작용과 관련된 데이터를 처리
  • 두 컴포넌트를 적절하게 조합하여 서버 부하를 줄이고 클라이언트 성능을 최적화

동적 데이터와 정적 데이터를 분리

  • 정적 콘텐츠는 SSG로 생성하고, 동적 데이터는 Server Components 또는 CSR을 통해 처리한다. (하이브리드 렌더링이 가능)
    예: 블로그 페이지의 본문은 정적으로 렌더링(SSG), 댓글은 동적으로 처리(CSR)

Nested Rendering

  • Server Components와 Client Components를 중첩해 사용
    예: 서버에서 데이터가 포함된 정적 헤더를 생성하고, 동적 데이터를 클라이언트에서 로드


결론

React는 CSR(Client-Side Rendering)을 중심으로 설계된 강력한 UI 라이브러리이지만, SEO 최적화, 초기 로딩 속도 개선, 데이터 패칭의 효율성 등 다양한 요구사항을 해결하기에는 추가적인 작업이 필요하다.

Next.js는 이러한 한계를 극복하기 위해 탄생한 React 기반의 프레임워크로, CSR, SSR, SSG, ISR, RSC(Server Components) 등 다양한 렌더링 방식을 유연하게 지원한다. 이를 통해 성능 최적화와 사용자 경험 개선, 개발 생산성 향상을 경험할 수 있다.

웹 렌더링의 주요 개념(CSR, SSR, SSG 등)을 이해함으로써, Next.js가 왜 현대 웹 애플리케이션 개발에 적합한 프레임워크인지, 그리고 이를 사용함으로써 어떻게 효율적인 렌더링을 구현할 수 있는지 알게 되었다.



ref.
Next.js 공식문서

0개의 댓글