때는 2024년 7월경. 처음으로 Next.js를 사용한 프로젝트를 진행했습니다.
SSAFY에서 진행한 첫 프로젝트로 팀원들과 함께 포부를 갖고 Next.js에 뛰어들었고..
결론적으로,
결과는 좋았지만..내 머릿속에서 완전히 이해하여 사용했는가? 를 질문하면 곧바로 "아니"라고 대답하는 결과를 맞았다고 생각합니다ㅜ.
팀원들과도 프로젝트가 끝난 뒤 회고하면서 가장 많이 했던 이야기가 "우리가 Next.js를 제대로 쓴 게 맞을까?"였으니 더 이상 말을 얹지는 않겠습니다.....
그런 과거의 나 자신을 회고하면서, 'Next.js에 대해 다시 한번 되짚어보고 내 코드를 제대로 된 지식을 갖고 살펴보자'라는 목표를 가지고 Next.js에 대한 공부를 진행하려고 합니다.
다만 먼저 코드를 보기보다는 Next.js가 무엇인지, React와는 어떤 차이가 있고 어떤 장점을 가지고 있는지 숙지하고 들어가 보도록 하겠습니다.
1. Next.js란 무엇인가?
프론트엔드 개발을 하다 보면, 이런 고민을 하는 사람이 왕왕 있을 거라고 생각합니다.
"내 웹사이트를 좀 더 빠르고, 깔끔하게 만들고 싶다."
바로 이 고민의 해결책으로 등장한 것이 바로 Next.js 요놈입니다.
Next.js는 React 기반의 프레임워크로 React의 장점은 그대로 살리면서, 개발자들이 더 쉽고 빠르게 웹 애플리케이션을 만들 수 있도록 업그레이드된 녀석이라고 보면 될 것 같습니다.
Next.js는 Vercel에서 개발했으며, 현재는 많은 기업과 개발자들이 Next.js로 선택지를 늘려가고 있죠.
React를 이미 알고 있거나 사용해 본 사람이라면, Next.js는 '좋아하던 메뉴에 좋아하는 시그니처 소스까지 얹은 요리'처럼 느껴질 수 있다고 생각합니다. 맛있는 거 + 맛있는 거 = 맛있는 것처럼요😋
@ : 잠시만요, 이건 뭔가요?
Next.js는 풀스택 웹 애플리케이션을 빌드하기 위한 React 프레임워크입니다.
Next.js docs를 열면 가장 먼저 나오는 문구로, 여기서 새로운 단어를 발견하셨나요?
맞습니다. 바로 풀스택 웹 애플리케이션이라는 단어죠. 놀랍게도, 프론트엔드 개발에만 초점을 맞춘 React와 달리 실제로 Next.js는 프론트엔드와 백엔드가 통합된, 진짜 풀스택 웹 애플리케이션이라고 볼 수 있다고 볼 수 있습니다.
아래에서 더 자세하게 알아보겠지만, Next.js는 특별한 기능이 하나 있습니다.
바로 SSR(Server Side Rendering)과 API Routes기능입니다. pages/api 디렉토리에 파일을 추가하면 바로 API 엔드포인트를 생성할 수 있죠. 이를 통해 백엔드 서버를 별도로 구축하지 않아도 데이터 처리를 위한 간단한 로직을 작성하고, 실행할 수 있답니다.
조금 더 긴 이야기가 될 수 있으니, 아래에 짧게 적어두고 다음 주제로 넘어가 보도록 하겠습니다!
Q. api폴더에 쓰기만 하면 정말 백엔드단이 실행되는 건가요?🤔
A. 그렇습니다. 정확히 말하자면 Next.js가 내장한 서버 환경에서 실행되는 것이라고 볼 수 있겠네요.
백엔드 서버를 따로 구축하지 않아도, API Routes 기능을 사용하면 간단한 백엔드 로직을 구현할 수 있기 때문에 프론트와 백을 하나의 코드 베이스에서 관리할 수 있다는 장점이 바로 여기서 나오는 거랍니다.
Q. 그럼 백엔드가 아예 없어도 된다는 건가요?🤔
A. 아닙니다! Next.js의 API Routes는 백엔드 서버를 별도로 구축할 필요가 없다는 것이지, 완전히 서버 없이 동작한다라고 생각하면 안 됩니다. API 요청 처리를 위해 Next.js가 자체적으로 Node.js 서버를 활용하고 있다고 생각하면 됩니다.
Q. 어떻게 동작하는 건가요?🤔
A. 간단하게는 두 단계로 동작한다고 보면 될 것 같습니다.
첫 번째로는 우리가 주로 사용하는 npm run dev나, next start를 통해 빌드할 시, Next.js는 내장된 Node.js서버를 실행합니다. 그러면 이 서버는 클라이언트 요청을 처리하고 API Routes로 정의된 엔드포인트를 실행합니다.
두 번째로 api폴더에 작성한 파일은 서버리스 함수처럼 작동하여, 브라우저에서 해당 경로로 요청이 들어올 시, Next.js가 처리해 결과를 반환하는 거라고 생각하면 될 것 같아요.
2. React와의 차이점
그래서 React와는 정확히 뭐가 다른 건데?🧐 하실 분들을 위해 더 자세히 알아보도록 하겠습니다.
Next.js가 React에서 업그레이드 됐다고 한 것처럼, React와 Next.js는 서로 뗄 수 없는 관계입니다.
1) DIY 키트 vs 완제품
React는 라이브러리입니다. 쉽게 말해서 필요한 기능을 직접 하나씩 조합해서 만드는 DIY 키트라고 보는 게 편할 것 같습니다.
예를 들어, 라우팅, 데이터 관리, 서버 통신 등을 사용하려면 각각의 라이브러리를 찾아 붙여서 사용해야 하는 수고로움이 있죠.
반면 Next.js는 프레임워크입니다. 즉, 개발자가 별도로 조립하지 않아도, 기본적으로 필요한 기능들을 제공하는 완제품이죠.
Next.js를 사용하면 이미 세팅된 라우팅, 렌더링 방식, 빌드 도구까지 손쉽게 사용할 수 있습니다.
2) 라우팅 방식
React는 SPA(Single Page Application) 방식으로 작동합니다.
앱 전체를 하나의 HTML 파일에 담고, 클라이언트에서 JavaScript를 통해 뷰를 업데이트합니다. 이 방식은 빠르고 유연하지만, 초기 로딩 속도가 느리고 SEO에 불리한 단점이 있습니다.
Next.js는 기본적으로 파일 기반 라우팅을 지원합니다. 프로젝트 디렉터리 안에 pages 폴더만 만들면, 폴더 구조에 따라 URL이 자동 생성됩니다.
3) 렌더링 방식
React는 기본적으로 클라이언트 사이드 렌더링(CSR)만 지원합니다. 즉, 브라우저가 사용자에게 빈 화면을 먼저 보여준 후, 필요한 데이터를 받아 화면을 완성합니다. 이 과정은 느리게 느껴질 수 있고, 검색 엔진이 크롤링하기에 적합하지 않습니다.
Next.js는 CSR, SSR, SSG, ISR 등 훨씬 다양한 렌더링 방식을 지원한다는 차이점이 있죠.
4) SEO 최적화
React로 만든 SPA는 SEO에 약하다는 단점이 있습니다. 초기 로딩 시 빈 화면이 렌더링 되기 때문입니다. Next.js는 서버 사이드 렌더링과 정적 사이트 생성을 통해 검색 엔진에 최적화된 페이지를 제공합니다. 특히 구글 검색 결과 상위 노출을 목표로 한다면, Next.js는 필수죠.
라우팅 방식 | 직접 설정 | 파일 기반 라우팅 |
렌더링 방식 | CSR | CSR, SSR, SSG, ISR 지원 |
SEO 최적화 | 약함 | 강함 |
개발 생산성 | 높은 자유도 | 기본 제공 기능으로 생산성 극대화 |
React는 자유도가 높은 도구라면, Next.js는 필요한 도구를 모두 갖춘 도구 상자라고 볼 수 있겠네요.
3. 그렇다면 Next.js만의 특징을 더 자세히 살펴보자!
위에서 알음알음 나왔던 Next.js만의 특징을 제대로, 더 자세히 알아보도록 합시다.
물론 세세하게 다 비교하지는 않고, 크게 세 가지 특징을 뽑아 작성해보려고 합니다.
1) 라우팅 구현 방식
2) 렌더링 기법
3) 클라이언트 컴포넌트 vs 서버 컴포넌트
이 세 가지가 제가 뽑은 Next.js의 특징이라고 생각하는 만큼, 이 부분에 대해 자세히 알아보도록 하겠습니다.
3-1. 라우팅 구현 방식
React와 Next.js를 비교할 때, 가장 큰 차이 중 하나는 라우팅 방식입니다.
라우팅은 사용자와 페이지를 연결하는 네비게이션의 핵심인데, 두 기술의 라우팅은 완전히 다르다고 보면 될 것 같습니다.
React
아까 차이점에서 React를 설명했던 DIY 키트라는 비유에 걸맞게, React는 여기서도 DIY 정신을 보여줍니다.
React는 기본적으로 라우팅 기능을 제공하지 않습니다. 대신, 라우팅을 구현하기 위해 react-router-dom과 같은 라이브러리를 사용해야 합니다.
import { BrowserRouter, Routes, Route } from 'react-router-dom';
function App() {
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/ciaom" element={<ciaom />} />
<Route path="/blog/:id" element={<blog />} />
</Routes>
</BrowserRouter>
);
}
물론 개발자가 원하는 대로 라우팅 규칙을 설정할 수 있지만 위 코드처럼 하나하나 적어줘야 하는 만큼 설정과 관리가 복잡하다는 건 인정할 수밖에 없네요.
Next.js
Next.js는 파일 기반 라우팅을 제공합니다.
말 그대로의 기능입니다. pages 폴더에 파일을 생성하기만 하면, 해당 파일의 경로가 자동으로 URL로 매핑되는 아주 편리한 기능입니다.
pages/
├── index.js -> /
├── ciaom.js -> /ciaom
처음 Next.js의 폴더 구조를 설정하기 위해 팀원들과 알아보다 '이게 진짜 된다고???' 하면서 보던 기억이 새록새록하네요.
참고로 대괄호[] 를 사용하는 파일 및 디렉터리 이름을 사용해서 동적 라우팅을 수행하는 것도 가능합니다.
3-2. 렌더링 기법
두 번째는 Next.js의 핵심이라고 볼 수 있는 렌더링으로 들어가 봅시다.
첫 번째로 살펴볼 것은 클라이언트 사이드 렌더링입니다.
1) CSR (Client-Side Rendering)
CSR은 React의 기본 렌더링 방식입니다. 초기에는 빈 HTML 파일만 제공되고, 브라우저가 JavaScript를 다운로드해 화면을 구성하는 순서로 이루어집니다.
- 브라우저가 HTML, JavaScript를 다운로드
- JavaScript가 실행되면서 필요한 데이터를 API로 받음
- 데이터를 기반으로 브라우저에 화면 렌더링
위와 같은 순서로 렌더링이 이루어지기 때문에
서버에서 렌더링 된 콘텐츠를 제공하지 않아 초기 로딩 속도가 느릴 수 있고, 검색엔진이 빈 HTML을 크롤링하기 때문에 SEO에 좋지 않다는 단점이 있습니다.
그렇기에 CSR 같은 경우는 실시간 데이터 변경이 많거나, 대화형식으로 이루어진 애플리케이션에서 많이 선택하는 렌더링 방식입니다.
2) SSR (Server-Side Rendering)
Next.js의 꽃이라고 할 수 있는 SSR입니다.
클라이언트가 아니라 서버 측에서 렌더링을 한다는 이름에 걸맞게 서버에서 HTML을 렌더링 하고 완성된 페이지를 클라이언트로 보내기 때문에 클라이언트는 JavaScript만 실행하면 된다는 장점이 있습니다.
클라리언트 사이드 렌더링과 달리
- 사용자의 페이지 요청
- 서버에서 HTML생성
- 클라이언트가 HTML과 JavaScript를 받아 화면 렌더링
의 순서로 이루어집니다.
서버에서 렌더링을 먼저 하기 때문에 초기 로딩 속도가 빠르고, 검색엔진이 HTML을 크롤링할 수 있기 때문에 SEO에 최적화됐다는 장점이 있습니다. 다만 서버 부하가 증가할 수 있다는 단점이 있지만요.
그렇기에 SEO가 중요한 블로그나 마케팅 페이지에서 많이 사용하고는 합니다.
제가 개발했던 프로젝트도 커뮤니티 형 프로젝트였기 때문에 SEO가 좋은 Next.js를 선택했었답니다..ㅎ-ㅎ
3) SSG (Static Site Generation)
이후로는 개발 때 사용하지 않았기에 다소 생소한 렌더링이기도 합니다.
SSG는 정적인 HTML페이지를 빌드 시 생성하고, 요청 시 제공하는 방식입니다.
빌드된 HTML은 CDN(Content Delivery Network)에 배포되어 매우 빠른 로딩 속도를 보여준다고 합니다.
초고속 로딩속도와 SEO최적화라는 장점이 있지만, 빌드 시에 데이터가 고정되기 때문에 실시간 데이터에는 적합하지 않다고 합니다.
그렇기에 문서 사이트나 블로그, 포트폴리오와 같은 정적 컨텐츠에 적합한 렌더링 방식인 것 같습니다.
4) ISR (Incremental Static Regeneration)
ISR은 SSG의 한계를 극복한 업그레이드 버전으로, 정적 사이트를 생성하면서도 실시간 데이터 갱신이 가능합니다.
특정 시간마다 페이지를 다시 생성해 정적 사이트의 성능적 장점과 동적 컨텐츠 제공이라는 두 마리 토끼를 잡는 렌더링 방식이라고 합니다.
짧게 정리하면 아래와 같은 상황에 각 렌더링 방식을 사용하면 좋을 것 같습니다✔️
CSR: 데이터 변경이 많고, SEO가 중요하지 않을 때.
SSR: SEO가 중요하고, 실시간 데이터 제공이 필요할 때.
SSG: 트래픽이 많고, 콘텐츠가 자주 변하지 않을 때.
ISR: SSG가 필요하지만, 특정 시간마다 데이터를 업데이트해야 할 때.
3-3. 클라이언트 컴포넌트 vs 서버 컴포넌트
마지막으로 살펴볼 것은 제가 프로젝트하면서 가장 골머리를 앓았던!!! 컴포넌트입니다.
Next.js 13에서 도입된 App Router는 개발자가 각 컴포넌트를 적절히 활용할 수 있도록 컴포넌트를 클라이언트 컴포넌트와 서버 컴포넌트로 구분하였다고 합니다.
즉, "어떤 작업이 클라이언트에서 실행되는 게 좋은지, 혹은 서버에서 실행되는 게 좋은지"에 초점을 맞춰 효율성과 성능을 극대화한 버전이라고 생각하면 될 것 같습니다.
1) 클라이언트 컴포넌트 (Client Components)
클라이언트 컴포넌트는 브라우저에서 실행되는 인터렉티브 UI를 구성합니다.
React의 기본 동작 방식을 그대로 따르며, 브라우저에서 데이터를 처리하고 이벤트를 처리합니다.
그렇기에 주로 사용자와의 상호작용이 많은 부분에 사용하고, 브라우저에서 렌더링 및 상태관리를 담당하기 때문에
React Hooks(useState, useEffect)를 이 클라리언트 컴포넌트에서 사용가능합니다.
주로 클라이언트 컴포넌트임을 알려주기 위해 코드의 제일 윗부분에
'use client';
를 선언하여 해당 코드가 브라우저에서 실행되는 클라이언트 컴포넌트임을 알려줍니다.
❗️추가 정보
'use client'를 사용하는 이유는 App Router 에서 기본적으로 컴포넌트가 서버 컴포넌트로 동작하기 때문입니다.
따라서 클라이언트 사이드에서 동작해야 하는 컴포넌트는 반드시 'use client'를 선언해야 합니다.
이 선언은 해당 파일과 하위 파일에 영향을 미치기 때문에 적재적소에 잘 사용해야 한답니다,,
2) 서버 컴포넌트 (Server Components)
반면 서버 컴포넌트는 서버에서 실행되어 클라이언트로 완성된 HTML을 전달합니다.
서버의 자원을 활용하기 때문에 훨씬 빠르고 효율적인 렌더링이 가능하게 한다는 게 특징이죠.
다만, 서버에서 데이터를 가져오고 HTML을 생성하는 역할과 / 사용자와 인터렉티브 할 수 있는 UI로 기능이 나뉘기 때문에
상태관리와 같은 클라이언트 컴포넌트 전용 React Hooks들을 사용하지 못하는 게 특징입니다..
이렇게 두 가지로 나뉘기 때문에 Next.js에서는 클라이언트 컴포넌트와 서버 컴포넌트를 조합해 사용하는 방식을 많이 사용합니다.
서버에서 데이터를 렌더링 한 후, 클라이언트에서 인터랙션을 추가하는 방식으로 각자에게 가장 잘하는 일을 나눠주고 나중에 최종 결과물을 합친다고 보면 편할 것 같아요.
정말 효율적인 방법이지만...
아래는 프로젝트를 진행하면서 제 바보 같은 코드에 대한 한탄이 적혀 있습니다.
이런 특징을 잘 이해하지 못한 채로 프로젝트에 뛰어들었던 저는....
서버에서 데이터를 가져오고 HTML을 생성하는 역할과 / 사용자와 인터렉티브 할 수 있는 UI
↑ 이 걸 제대로 이해하지 못해 두 가지를 한 파일에 다 때려 넣는 실수를 저질렀고..
모든 파일에 "use client"를 쑤셔 박는 지점까지 다다랐습니다..ㅋㅋㅋ...ㅋㅋ...
심지어 상위 파일에서 클라이언트 컴포넌트 선언을 해주면 꼬리물기로 하위도 다 클라이언트로 지정되는 바람에
하나씩 고쳐나가긴커녕 완전히 뒤집어엎어야 하는 상황까지 갔습니다....🥲
Next.js를 사용할 때는 꼭..! 사전에 특징을 다 이해하고 뛰어들기를 추천드립니다....
각설하고, 이렇게 Next.js에 대한 기본적 특징을 알아봤습니다.
이제 Next.js에 대한 특징도 어느 정도 이해했으니 다음에는 제 코드를 하나씩 뜯어보며 Next.js에 대해 더 깊이 알아보는 시간을...🥲
출처
'Framework > Next.js' 카테고리의 다른 글
Next에도 prepatching이 필요할까? (0) | 2025.04.06 |
---|---|
SEO. 그게 어떻게 돌아가는 건데? (3) | 2025.01.22 |