[프레임워크] Next.js 넌 누구니?

응애개발자·2025년 7월 11일

Frontend

목록 보기
2/4

이 포스팅에선 Next.js 가 왜 생겨났는지, React와 Next.js 의 차이에 대해 설명하는 내용을 포함하고 있습니다.

프론트엔드 스터디에서 진행하는 "개발 블로그 개발" 회의 도중, 어떤 프론트엔드 라이브러리 혹은 프레임워크를 선택할지 의견을 나누게 되었습니다.

결론적으로 쟁쟁한 후보들 React 와 React 와 React 등... 을 제치고 Next.js 가 선택되었는데

Next.js 가 뭐고 왜 선택하게 되었는지 그리고 개발을 진행하면서 알아두면 좋은점에 대해 간단히 정리해보려고 합니다.


Next.js 넌 누구니? 🤷

니다## 1. Next.js 의 등장

Next.js 가 왜 등장했는지 알기 위해서는 먼저
CSR 과 SSR 에 대해 간단하게 짚고 넘어가야 할 필요가 있습니다.

1.1 CSR

여러분이 잘 아시고 저도 많이 사용했던 React 가 대표적인 CSR 방식입니다.

CSR은 말 그대로 브라우저(클라이언트)에서 모든 UI를 그리는 방식입니다.

CSR의 흐름은 아래 이미지와 같습니다.

간단히 말해,

  1. 브라우저가 서버에 접속하면, 서버는 HTML 껍데기JS 번들 파일만 딱 보내줍니다.
// 예시
<!DOCTYPE html>
<html>
<head>
    <title>My App</title>
</head>
<body>
    <div id="root"></div>  <!-- 빈 div만 있음 -->
    <script src="app.js"></script>  <!-- JavaScript 파일 -->
</body>
</html>
  1. 브라우저는 JS를 받아서 실행하고, 그때부터 모든 UI를 브라우저가 직접 그립니다.
// app.js
function createPage() {
    const root = document.getElementById('root');
    
    // HTML 구조를 JavaScript로 만들기
    root.innerHTML = `
        <header>
            <h1>내 웹사이트</h1>
            <nav>
                <a href="#home">홈</a>
                <a href="#about">소개</a>
            </nav>
        </header>
        <main>
            <h2>환영합니다!</h2>
            <p>이 페이지는 JavaScript로 만들어졌습니다.</p>
        </main>
    `;
}

// 페이지 로드 시 실행
createPage();
  1. 페이지 이동이나 데이터 변경도 서버에 새로 요청하지 않고, JS가 알아서 처리합니다.
// 예시
// 페이지 이동 (실제로는 같은 HTML 파일)
function goToAbout() {
    // 기존 내용 지우기
    document.getElementById('root').innerHTML = '';
    
    // 새로운 내용 만들기
    document.getElementById('root').innerHTML = `
        <h1>소개 페이지</h1>
        <p>저는 개발자입니다.</p>
        <button>홈으로</button>
    `;
}

function goToHome() {
    // 다시 홈 페이지 내용으로
    document.getElementById('root').innerHTML = `
        <h1>홈 페이지</h1>
        <p>환영합니다!</p>
        <button>소개로</button>
    `;
}

보시면 처음 받은 HTML 껍데기에 Javascript 로 DOM 을 직접 조작하면서 UI 를 바꾸게 됩니다.

페이지 이동조차도 내부적으로는 똑같은 HTML 파일에 덮어씌우는 방식으로 동작하기 때문에

하나의 페이지를 사용한다고 해서 "SPA(Single Page Application)" 라고 불립니다.

이 방식의 장점으로는 아래 두가지가 있습니다.

  • 앱처럼 부드러운 UX를 제공할 수 있습니다.
    (서버를 거칠 필요 없이 클라이언트에서 바로 적용하면 되기 때문)
  • 서버 부하가 줄어듭니다.
    (HTML을 매번 만들 필요가 없음)

하지만 CSR도 단점이 있습니다.

  • 초기 로딩이 느릴 수 있습니다.
    (JS 파일을 다 받아서 실행해야 화면이 보이기 때문)
  • SEO(검색엔진 최적화)에 불리합니다.
    (크롤러는 보통 서버에서 주는 HTML 파일을 읽는데, CSR 방식은 HTML 껍데기만 주기 때문)

이것이 팀원 대부분이 React 개발 경험이 제일 많음에도 React 를 선택하지 않은 이유입니다.

개발하는 테크 블로그가 더 많이 노출되기를 바랬고
빠른 초기 로딩으로 UX 를 좋게 하고 싶었기 때문입니다.

블로그 특성상 많은 인터렉션도 필요하지 않아 CSR 의 장점도 아주 매력적이지는 않았습니다.

1.2 SSR(Server Side Rendering)

SSR 을 직역하면 "서버 측 렌더링..."
그게 무슨 뜻일까요?

여러분이 SSR 방식의 사이트인 https://something.com/article?id=7 을 클릭했다고 가정해봅시다.
그럼 다음과 같은 일이 일어납니다.

  1. 브라우저가 서버에게 "사용자가 7번 글을 보고 싶어해요!"라고 요청합니다.
  2. 서버는 데이터베이스에서 7번 글에 대한 정보를 가져옵니다.
  3. 그 내용을 HTML 템플릿 에 끼워 넣어 브라우저에 통째로 보내줍니다.
  4. 브라우저는 받은 HTML을 그대로 보여주면 끝.

서버 사이드 렌더링이 뭔지 대충 아시겠나요?

말그대로

보려고 하는 웹페이지의 화면을 서버에서 전부 렌더링한 다음 우리에게 주겠다

라는 것입니다.

이 방법은 서버측에서 완성된 HTML 을 바로 주기 때문에
초기 화면 렌더링이 빠르다는 장점이 있습니다.

여기서 이런 의문을 가질 수 있습니다.

CSR 은
JS 번들을 클라이언트에 보냄 -> 클라이언트가 JS 파싱하여 HTML 생성 -> 화면에 보여줌

SSR 은
서버가 JS 파싱하여 HTML 생성 -> 완성된 HTML 을 클라이언트에 보냄 -> 화면에 보여줌

순서만 바뀐거 같은데 왜 SSR 이 초기 렌더링이 더 빠르지??

저도 어차피 JS 번들로 HTML 을 만들어 보여주는건 똑같은데 왜 SSR 이 빠른지 잘 이해하지 못했습니다.

빠른 이유를 설명드리자면...
사실 SSR 방식으로 보내주는 HTML 에는 기능이 들어있지 않습니다.

말그대로 화면에 보이는 UI 만 전달할 뿐이지 기능은 넣지 않고 보내게 됩니다. 빠르게 UI 만 보이게 해주는 것이죠

기능이 들어있는 JS 번들은 페이지를 전달하고 나중에 전송되어
화면에 적용되게 됩니다.

나중에 받은 기능이 UI 뿐인 페이지에 적용되는 것을 "하이드레이션" 이라고 합니다.

그래서 매우 빠르게 화면이 렌더링 된것처럼 보이는 것이죠

크게 아래와 같은 단점이 있죠 🙄

  • 매번 서버가 HTML을 만들어야 하므로 서버에 부하가 큽니다.
  • 페이지 이동 시마다 전체를 다시 요청해야 하므로 깜빡거림 현상이 발생할 수 있습니다.
  • 사용자와의 상호작용(동적 UI)이 제한적입니다.

예를 들어서 버튼을 클릭하면 현재 좋아요 개수가 표시되는 기능이 있다고 할 때,

SSR 만 사용하는 방식에서는 버튼을 클릭하면
좋아요 개수를 DB 에서 가져와 HTML 에 합치고 그 HTML 파일 전부를 다시 줍니다.

해당 페이지가 아주 길고 복잡한 HTML 파일이라면,
단지 하트 개수 그 숫자 하나를 바꾸기 위해 HTML 파일 전체를 다시 서버로부터 받아야 한다는 것이죠.


1.3 Next.js

위에서 언급했던 방식들의 단점 때문에
"SSR의 장점(빠른 첫 화면, SEO) + CSR의 장점(동적 UI, 부드러운 UX)"
둘 다 잡고 싶다는 니즈가 생겼고,
그래서 Next.js 같은 프레임워크가 등장하게 됩니다.

Next.js는

  • 서버에서 미리 HTML을 만들어 보내주면서도(SSR 장점),
  • 클라이언트에서 React의 동적 기능도 그대로 쓸 수 있게 해줍니다(CSR 장점).

즉,
SSR과 CSR의 장점을 모두 취할 수 있는 하이브리드 프레임워크라고 보면 됩니다!

Next.js 외에도 SSR 프레임워크로 SveltKit, Nuxt 등 유사한 다른 프레임워크들이 있습니다.

Next.js 가 너무 많은 기능을 지원하려고 하다 보니 무거워져 성능 이슈가 발생한다는 의견도 있었지만,

스터디원들이 이미 React 에 익숙해져있고,
Next.js 의 커뮤니티가 커 빠른 도움을 얻을 수 있기 때문에 이번 프로젝트에서는 Next.js 를 선택하게 되었습니다.


React 와의 차이점 📊

자 그럼 Next.js 로 개발을 진행해야 하는데
도대체 Next.js 는 React 와 어떻게 다를까요?

1. 라우팅 방식의 차이

🔴 React (Client-Side Routing)

React에서는 보통 react-router-dom 같은 라이브러리를 사용해서 라우팅을 구현합니다.

// React에서 라우팅 설정
import { BrowserRouter, Routes, Route } from "react-router-dom";

function App() {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/about" element={<About />} />
        <Route path="/contact" element={<Contact />} />
      </Routes>
    </BrowserRouter>
  );
}

🟢 Next.js (File-Based Routing)

Next.js에서는 파일 시스템 기반으로 라우팅이 자동으로 설정됩니다!

pages/
├── index.js          → "/"
├── about.js          → "/about"
├── contact.js        → "/contact"
└── blog/
    ├── index.js      → "/blog"
    └── [id].js       → "/blog/1", "/blog/2" 등

Next.js 의 라우팅 방식

  • 파일 만들기 → 자동으로 라우트 생성
  • 폴더 구조가 곧 URL 구조
  • 설정 코드 없이 바로 사용 가능

근데 찾아보니 Next.js 에서는 Page 라우팅 방식App 라우팅 방식 두가지가 존재합니다.

// Page 라우팅
pages/
 ├─ index.js        → /
 ├─ about.js        → /about
 └─ products/
     └─ [id].js     → /products/:id
//App 라우팅
app/
 ├─ layout.tsx      → 루트 레이아웃
 ├─ page.tsx        → /
 ├─ about/
 │   ├─ page.tsx    → /about
 │   └─ layout.tsx  → /about 전용 레이아웃
 └─ products/
     └─ [id]/
         └─ page.tsx → /products/:id

Next 13 버전 이후로는 앱 라우터를 권장하고 있기 때문에,
저희는 앱 라우터를 선택했습니다.

2. 렌더링 방식의 차이

🔴 React (CSR Only)

// React는 기본적으로 클라이언트 사이드 렌더링만 지원
function App() {
  return (
    <div>
      <h1>이 내용은 JavaScript가 로드된 후에 보입니다</h1>
    </div>
  );
}

이전에도 언급했듯이 React 는 CSR 방식을 사용합니다.

🟢 Next.js (하이브리드 렌더링)

// 1. SSR (Server Side Rendering) - 기본값
export default function HomePage() {
  return <h1>서버에서 미리 렌더링된 페이지</h1>;
}

// 2. SSG (Static Site Generation)
export async function getStaticProps() {
  return {
    props: { data: '빌드 시점에 생성된 데이터' }
  };
}

// 3. CSR (Client Side Rendering)
'use client';
export default function DynamicPage() {
  const [data, setData] = useState(null);
  // 클라이언트에서만 실행
}

Next.js 의 렌더링 방식

  • 원하는 렌더링 방식 선택
  • SSR, SSG, CSR 가능
  • SSG란... 빌드 시에 모든 페이지를 HTML로 미리 생성하는 방식입니다.

3. 데이터 Fetching 방식의 차이

🔴 React에서 데이터 가져오기

useEffect(() => {
  fetch("/api/user") ...
}, []);
  • useEffect 를 사용해서 API 호출을 합니다.
  • 페이지가 빈 상태로 먼저 보이고 그 다음에 API 요청을 해서 데이터를 받아옵니다.

🟢 Next.js에서 데이터 가져오기

export async function getServerSideProps() {
  const res = await fetch("https://api.example.com/user");
  const user = await res.json();

  return {
    props: { user },
  };
}

Next.js는 서버에서 미리 데이터를 가져오는 기능이 있습니다. 위에서 사용한 getServerSideProps 를 통해 가능하죠.
사용자가 페이지를 요청하면, 브라우저에 보내기 전에 서버에서 데이터를 먼저 가져와서 화면에 넣은 HTML을 만들어 줍니다.

Next.js 의 Fetch

  • 서버에서 데이터를 먼저 받아오고 → 받아온 데이터를 props로 컴포넌트에 전달해요.
  • 브라우저는 이미 데이터가 들어있는 완성된 HTML을 받습니다.
  • 이 방식은 SEO 에도 유리합니다. 😉

4. 이미지 처리 방식의 차이

🔴 React에서 이미지 사용

// React에서는 일반 HTML img 태그 사용
function Profile() {
  return (
    <div>
      <img src="/profile.jpg" alt="프로필" />
      {/* 최적화 없음, lazy loading 없음 */}
    </div>
  );
}

🟢 Next.js에서 이미지 사용

// Next.js에서는 최적화된 Image 컴포넌트 사용
import Image from "next/image";

function Profile() {
  return (
    <div>
      <Image
        src="/profile.jpg"
        alt="프로필"
        width={300}
        height={300}
        priority // 중요한 이미지는 우선 로드
      />
      {/* 자동 WebP 변환, lazy loading, 반응형 이미지 */}
    </div>
  );
}

Next.js의 이미지 최적화:

  • 자동으로 WebP 형식으로 변환 (더 작은 파일 크기)
  • 자동 lazy loading (화면에 보일 때만 로드)
  • 반응형 이미지 자동 생성
  • 이미지 크기 최적화

마치며...

Next.js 가 왜 생겨났고 React 와의 차이점이 뭔지 정리해봤습니다.
저처럼 React 는 사용해봤지만 Next.js 를 처음 사용하시는 분들에게 도움이 됐으면 좋겠네요 😊

0개의 댓글