Web 렌더링 방식 비교 (CSR, SSR, SSG)

Soyeon·2025년 6월 29일
3
post-thumbnail

웹 페이지를 보여주는 방법엔 대표적으로 3가지가 있다.
CSR, SSR, SSG 각 방식의 정의와 동작 과정 그리고 장단점을 정리해본다.

CSR (Client Side Rendering)

클라이언트 측 렌더링

먼저 빈 상자(html)만 받고, 안에 내용은 JS가 와서 화면을 채운다.

동작 과정

  1. 브라우저가 index.html을 로드함
  2. JS 번들이 로드됨 (React, Vue, ...)
  3. React가 클라이언트에서 DOM을 생성함
  4. 사용자에게 화면이 보이기 시작

장단점

  • 페이지 간 전환이 빠르고 백엔드 의존도가 낮다.
  • but, JS 로딩 전까지 빈 화면이다. (LCP 느림)

예제 코드

// App.tsx
import { useEffect, useState } from 'react';

const App = () => {
  const [data, setData] = useState<string | null>(null);

  useEffect(() => {
    // CSR에서 데이터를 클라이언트에서 fetch
    fetch('/api/data')
      .then((res) => res.json())
      .then((json) => setData(json.message));
  }, []);

  return (
    <div>
      <h1>클라이언트 렌더링 예제</h1>
      {data ? <p>데이터: {data}</p> : <p>로딩 중...</p>}
    </div>
  );
};

export default App;


SSR (Server Side Rendering)

서버 측 렌더링

서버에서 이미 내용을 다 만들어서 HTML을 완성해 보내준다.

동작 과정

  1. 클라이언트가 페이지를 요청
  2. 서버가 React를 실행해서 HTML 생성
  3. 완성된 HTML을 응답으로 보냄
  4. 브라우저는 HTML을 렌더링하고, 이후 JS를 로딩하여 interactivity 부여

장단점

  • SEO에 유리하다. (HTML이 미리 렌더링되므로)
  • 초기 로딩 속도가 빠르다.
  • but, 요청할 때마다 서버에서 렌더링하므로 느려질 수 있다.

예제 코드

// pages/ssr.tsx
import { GetServerSideProps } from 'next';

interface Props {
  message: string;
}

const SSRPage = ({ message }: Props) => {
  return (
    <div>
      <h1>서버 사이드 렌더링 예제</h1>
      <p>{message}</p>
    </div>
  );
};

export const getServerSideProps: GetServerSideProps = async () => {
  // 서버에서 데이터 패칭
  const res = await fetch('https://api.example.com/message');
  const data = await res.json();

  return {
    props: {
      message: data.message,
    },
  };
};

export default SSRPage;


SSG (Static Site Generation)

정적 사이트 생성

페이지를 미리 만들어 두고, 요청 시 그걸 던져준다.

동작 과정

  1. next build 같은 시점에 모든 HTML이 미리 생성됨
  2. 사용자가 요청하면, 이미 생성된 HTML을 즉시 전달
  3. 이후 JS가 로딩되어 interactivity 부여

장단점

  • 매우 빠르고 서버 없이도 배포 가능하다.
  • but, 페이지 수가 많을수록 빌드 시간이 길어진다.
  • 실시간 데이터 반영이 불가능하다.

예제 코드

// pages/ssg.tsx
import { GetStaticProps } from 'next';

interface Props {
  message: string;
}

const SSGPage = ({ message }: Props) => {
  return (
    <div>
      <h1>정적 사이트 생성 예제</h1>
      <p>{message}</p>
    </div>
  );
};

export const getStaticProps: GetStaticProps = async () => {
  // 빌드 타임에 한 번 실행됨
  const res = await fetch('https://api.example.com/message');
  const data = await res.json();

  return {
    props: {
      message: data.message,
    },
    revalidate: 60, // ISR (옵션): 60초마다 새로 고침 가능
  };
};

export default SSGPage;


profile
탄탄한 개발자로 살아남기🗿

1개의 댓글

comment-user-thumbnail
2025년 6월 29일

오 사진이랑 코드랑 같이 보니까 이해가 잘되는것 같아요!

답글 달기