[1012] React복습: 페이지 라우팅, SSR, CSR

방법이있지·2025년 10월 12일

웹개발

목록 보기
18/19
post-thumbnail

참고: 한 입 크기로 잘라 먹는 리액트 - 인프런

SSR은 Song Sang Rok이 아니라 Server Side Rendering을 뜻합니다.

페이지 라우팅

라우팅이란 사용자가 요청한 경로에 따라 적절한 페이지를 보여주는 기능입니다.

이를테면, https://strawberry-tree.github.io/cv로 접속하면 CV 페이지가, https://strawberry-tree.github.io/projects로 접속하면 프로젝트 페이지를 보여줘야겠죠.

라우팅이 이루어지는 원리에 따라, 웹사이트는 MPA(multi page application)SPA(single page application)으로 나눌 수 있습니다.

MPA(Multi Page Application)

MPA 방식의 웹사이트에선, 서버에 이미 여러 개의 완성된 html 페이지가 존재합니다. 브라우저가 경로를 요청하면 서버가 해당 페이지를 찾아 반환하게 됩니다.

SSR (Server Side Rendering)

일반적으로 MPA 방식에서 페이지 내용을 화면에 렌더링하는 데는 SSR이 사용되는데요, 이는 서버가 렌더링을 한다는 뜻입니다. 서버가 미리 완성된 html 파일을 만들어 브라우저에 전송하고, 브라우저가 그대로 화면에 띄우게 됩니다.

이때 MPA와 SSR은 흔히 함께 쓰이지만 동일 개념은 아닙니다. MPA는 서버에 여러 페이지가 존재하는 구조, SSR은 그 페이지를 서버에서 완성해서 보내주는 렌더링 방식을 의미합니다.

MPA 방식의 단점

MPA 방식은 쾌적한 페이지 이동 경험에 방해가 된다는 단점이 있습니다. 그 이유를 2가지로 정리해 보자면,

1. 비효율적인 페이지 이동

/cv 페이지              /projects 페이지
┌──────────────┐       ┌──────────────┐
│   Header    │       │   Header    │ <- 동일한데 재렌더링
├──────────────┤  -->  ├──────────────┤
│             │       │             │
│  CV         │       │   Projects  │ <- 재렌더링
│             │       │             │
├──────────────┤       ├──────────────┤
│   Footer    │       │   Footer    │ <- 동일한데 재렌더링
└──────────────┘       └──────────────┘

MPA 방식에서는 페이지를 이동할 때마다, 화면 전체에 렌더링된 내용이 모두 제거되고, 새로운 페이지를 처음부터 다시 렌더링됩니다.

그러니까 헤더, 푸터 등 모든 페이지에 들어가는 공통 요소도 매번 다시 그려지므로 비효율적입니다. 렌더링 과정에서 페이지 전체가 한번 깜빡이는 게 이런 이유 때문이죠.

2. 서버 부하 증가

MPA 방식에서는 페이지를 이동할 때마다 서버에 새 페이지를 요청합니다. 즉, 사용자가 많아질수록 서버 부하가 심해집니다.

SPA (Single Page Application)

React는 페이지 이동 시 MPA의 단점을 해결하기 위해, SPA 방식을 채택했습니다.

SPA의 경우 서버에 페이지가 단 하나 (index.html) 존재합니다. 추가로 React 컴포넌트나 각종 유틸리티 함수가 담긴 별도의 JavaScript 파일들도 존재합니다.

절대로 사용자가 접근할 수 있는 페이지가 하나라는 뜻이 아닙니다. (저도 맨 처음에 이게 헷갈려서 리액트로는 페이지를 하나 밖에 못 만드나? 싶은 줄 알았습니다.)

CSR (Client Side Rendering)

사용자가 어떤 경로로 접속하든, 이러한 과정을 따릅니다.

  • 1단계 서버는 항상 index.html을 반환하고, 브라우저는 먼저 index.html을 렌더링한다
    • 이때 index.html엔 JS 파일을 실행하는 태그만 있습니다. 즉 index.html엔 아무 내용이 없어, 아주 잠깐 빈 화면이 뜨게 됩니다.
  • 2단계 서버는 모든 React 컴포넌트/유틸리티에 사용되는 JS 파일들을 하나의 번들 파일로 묶어 브라우저로 전달한다
    • 이러한 번들링 과정을 Vite 같은 친구들이 해 줍니다
    • 이러한 번들 파일을 React 앱으로도 부릅니다
  • 3단계 브라우저는 번들 파일을 실행하며, <App> 컴포넌트부터 순서대로 렌더링한다

이와 같이 서버가 아니라 브라우저가 화면에 뜨는 요소를 렌더링하며, 이를 CSR(Client-Side Rendering)이라 합니다. MPA와 SSR의 관계랑 비슷하게, SPA는 페이지 구조, CSR은 렌더링 방식이고 동일한 개념이 아님에 유의합시다.

페이지 이동 시

/cv 페이지              /projects 페이지
┌──────────────┐       ┌──────────────┐
│   Header    │       │   Header    │ <- 유지
├──────────────┤  -->  ├──────────────┤
│             │       │             │
│  CV         │       │   Projects  │ <- 너만 교체
│             │       │             │
├──────────────┤       ├──────────────┤
│   Footer    │       │   Footer    │ <- 유지
└──────────────┘       └──────────────┘
+ 이 과정에서 서버 요청은 이루어지지 않음

기존 MPA 방식에서는 페이지를 이동할 때마다 전체 페이지를 없애고 다시 렌더링해야 했지만, SPA 방식에서는 React 앱(JS 번들 파일)을 이용해 브라우저가 자체적으로 필요한 컴포넌트만 교체합니다.

그러므로 헤더, 푸터 등 모든 페이지에서 동일한 컴포넌트는 그대로 남아 있고, 바뀌는 컴포넌트만 즉시 불러와 화면에 보여주게 됩니다.

결국에는 페이지 이동이 매끄럽고 빠르며, 서버에도 요청이 전혀 가지 않기 때문에 서버 부하도 줄어듭니다.

실전에서는

흔히는 React Router 같은 패키지로 페이지 라우팅을 구현합니다. 이런 패키지는 (1)컴포넌트가 현재 브라우저의 주소를 읽어올 수 있게, 그리고 (2)컴포넌트가 주소의 변화를 감지할 수 있게 처리해 줍니다.

function App() {
  return (
    <>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/new" element={<New />} />
        <Route path="/diary" element={<Diary />} />
        <Route path="*" element={<NotFound />} />
      </Routes>
    </>
  );
}

얘를 들어 이런 코드에서는, 주소가 /new 에서 /diary로 바뀌면 App 컴포넌트 내부의 New 컴포넌트가 Diary 컴포넌트로 교체되게 됩니다.

SSR, CSR 모두 지원하는 Next.js

특이하게 저의 최애 프레임워크인 Next.js 같은 경우는 SSR과 CSR의 장점을 모두 활용할 수 있습니다.

첫 페이지 로드는 SSR로 완성된 HTML을 받아오고, 이후 페이지 이동은 CSR 방식으로 필요한 부분만 바꿔주는 식이죠.

예를 들어 프로젝트 목록 페이지로 이동한다면...

1단계 사용자가 /projects로 이동하면, 필요한 <ProjectsPage> 컴포넌트만 불러옵니다. 헤더, 푸터 등 공통 컴포넌트는 그대로 유지됩니다.

2단계 <ProjectsPage> 안에 <ProjectList>라는 서버 컴포넌트(Server Component)가 있다고 합시다.

  • <ProjectList>는 DB에서 프로젝트 목록 데이터를 가져와야 합니다.
  • 서버가 DB에서 데이터를 미리 조회해서, <ProjectList>를 완성된 HTML 형태로 만들어 보내줍니다.

3단계 브라우저가 HTML을 받으면, 로딩 화면 없이 바로 프로젝트 목록이 표시됩니다.

순수 CSR과 비교

일반 React(순수 CSR)에서는:

  • 빈 화면 렌더링 → 브라우저가 API 호출 → 로딩 표시 → 내용 표시

Next.js의 SSR에서는:

  • 서버가 미리 데이터 조회 + 렌더링 → 완성된 화면 바로 표시

물론 서버에서 렌더링하는 시간도 걸리긴 하지만, 서버-DB 간 통신이 빠른 경우가 많아서 대부분 사용자 체감 속도가 더 빠릅니다. 특히 의미있는 콘텐츠를 빈 화면 대신 먼저 보여줄 수 있는게 장점입니다.

그래서 Next.js에선 페이지 이동은 빠르게(CSR), 데이터는 미리 준비해서(SSR) 보여주는 등 상황에 맞게 선택할 수 있습니다. 우와~~

profile
뭔가 만드는 걸 좋아하는 개발자 지망생입니다. 프로야구단 LG 트윈스를 응원하고 있습니다.

0개의 댓글