728x90
728x90
렌더링 방식 정리 (CSR(Client Side Rendering), SSR(Server Side Rendering), SSG(Static Site Generation), ISR(Incremental Static Regeneration))
들어가며
- Next.js의 렌더링 방식인 CSR(Client Side Rendering), SSR(Server Side Rendering), SSG(Static Site Generation), ISR(Incremental Static Regeneration)에 대해 정리해본다.
- Next.js에서 페이지를 작성하면 기본적으로 CSR 방식으로 렌더링된다.
CSR(Client Side Rendering)
개념
- 브라우저에서 자바스크립트 파일을 다운로드한 후, 클라이언트 측에서 렌더링을 수행하는 방식
- 전통적인 React SPA(Single Page Application) 방식
- 사용자 상호작용이 많은 페이지나 실시간 데이터가 필요한 경우에 사용하면 유용하다.
작동 방식
- 사용자가 페이지에 접근하면 HTML과 함께 자바스크립트 파일을 다운로드 한다.
- 브라우저는 자바스크립트 파일을 실행하여 페이지를 렌더링한다.
- 이후 페이지 전환은 클라이언트 측에서만 처리되므로 빠르다.
장점
- 서버(Server)는 정적 파일만 제공하고, 렌더링은 클라이언트(Client)에서 수행하므로 수버 부담이 적어진다.
- 첫 페이지를 불러온 후에는 클라이언트에서 모든 페이지를 처리하므로 전환 속도가 빠르다.
단점
- 초기 HTML 파일이 빈 상태로 불러와지기 때문에 검색 엔진 크롤러가 컨텐츠를 인식하지 못할 수 있다.
- 자바스크립트 파일을 다운로드하고 실행하는 데 시간이 걸리기 때문에 초기 페이지 로딩 시간이 느릴 수 있다.
예시 코드
- Next.js 에서 기본적으로 모든 페이지는 CSR 방식으로 작동한다.
- @getServerSideProps@ 또는 @getStaticProps@를 사용하지 않으면, CSR 방식이 적용된다.
- @useEffect@ 훅과 @useState@ 훅을 이용하여 구현할 수 있다.
import { useEffect, useState } from 'react';
export default function Home() {
const [time, setTime] = useState('');
useEffect(() => {
setTime(new Date().toISOString());
}, []);
return <div>현재 클라이언트 시간: {time}</div>;
}
⇒ @useEffect@ 훅을 사용하여 클라이언트에서 데이터를 가져온다.
⇒ 클라이언트 측에서만 데이터 요청이 이루어지고 갱신된다.
⇒ 페이지 접근 시, 서버 요청이 없고 자바스크립트를 통해 클라이언트에서 렌더링한다.
SSR(Server Side Rendering)
개념
- 서버에서 HTML을 렌더링한 후 클라이언트에 완성된 HTML을 전달하는 방식
- Next.js에서 기본적으로 지원하는 방식
- 초기 페이지 로딩 속도가 빠르고, SEO에 유리하다는 장점이 있다.
SSR은 서버에서 HTML을 미리 렌더링하고 클라이언트에 완성된 HTML을 전달하는 방식이다. 따라서 초기 페이지 렌더링 속도가 빠르고, SEO에 유리하다.
작동 방식
- 사용자가 페이지에 접근하면 서버로 요청(Request)이 전송된다.
- 서버에서 해당 페이지를 렌더링하여 HTML 파일을 생성한다.
- 생성된 HTML 파일이 클라이언트로 전송된다.
- 브라우저는 HTML을 파싱한 후, 리액트(React)를 통해 추가적인 상호작용 기능을 활성화한다. (Hydration)
장점
- 검색 엔진이 미리 렌더링된 HTML을 쉽게 크롤링할 수 있다. (SEO 최적화)
- 서버에서 미리 렌더링된 HTML을 제공하기 때문에, 첫 페이지 로딩 속도가 빠르다.
단점
- 모든 요청마다 서버에서 HTML을 생성해야 하므로 트래픽이 많을 경우 서버 부담이 크다.
- 서버에서 HTML을 생성하는 시간이 추가되기 때문에 클라이언트에서 페이지를 볼 때까지 시간이 걸릴 수 있다.
예시 코드
- @getServerSideProps@ 함수를 사용하여 구현할 수 있다.
import { GetServerSideProps } from 'next';
interface Props {
time: string;
}
export default function Home({ time }: Props) {
return <div>현재 서버 시간: {time}</div>;
}
export const getServerSideProps: GetServerSideProps = async () => {
return {
props: {
time: new Date().toISOString(),
},
};
};
⇒ @getServerSideProps@ 함수는 서버에서만 실행되며, 클라이언트에서 호출되지 않는다.
⇒ 페이지에 접근할 때마다 서버에서 데이터를 가져와 새롭게 렌더링한다.
SSG(Static Site Generation)
개념
- 웹 페이지를 미리 생성하여 HTML 파일로 저장하는 방식
- 빌드 시점에 페이지를 미리 생성한다.
- 빌드된 HTML 파일은 서버로 정적 파일로 제공된다.
장점
- 페이지 로딩 속도가 매우 빠르다.
- 서버 부하를 줄일 수 있다.
- SEO에 유리하다.
단점
- 빌드 이후에 생성된 페이지는 정적이므로, 데이터가 변경되면 업데이트 되지 않는다.
예시 코드
- @getStaticProps@ 함수를 사용하여 구현할 수 있다.
const HomePage = ({ posts }) => {
return (
<div>
<h1>Blog Posts</h1>
<ul>
{posts.map((post) => (
<li key={post.id}>{post.title}</li>
))}
</ul>
</div>
);
};
// 빌드 타임에 호출
export async function getStaticProps() {
// 데이터를 가져오는 API 호출
const res = await fetch('https://jsonplaceholder.typicode.com/posts');
const posts = await res.json();
return {
props: {
posts,
},
};
}
export default HomePage;
⇒ @getStaticProps@ 함수는 빌드 시에만 실행되며, 빌드 후 변경되지 않는 정적 페이지를 만든다.
ISR(Incremental Static Regeneration)
개념
- SSG(Static Site Generation)와 유사하게 정적 파일을 생성하지만, 특정 주기로 페이지를 재생성하여 최신 데이터를 반영하는 방법
장점
- SSG의 빠른 로딩 속도
- SSR의 최신 데이터 제공
단점
- 일정 주기로만 데이터가 업데이트 되므로, 실시간 데이터 반영은 어렵다.
사용 예시
- @getStaticProps@ 함수에 @revalidate@ 옵션을 추가하여 구현할 수 있다.
import { GetStaticProps } from 'next';
interface Props {
data: string;
}
export default function ISRPage({ data }: Props) {
return (
<div>
<h1>Incremental Static Regeneration</h1>
<p>데이터: {data}</p>
</div>
);
}
export const getStaticProps: GetStaticProps = async () => {
const res = await fetch('https://jsonplaceholder.typicode.com/posts/1');
const data = await res.json();
return {
props: {
data: data.title,
},
revalidate: 60, // ISR, 60초마다 페이지를 재생성
};
};
(참고) SPA(Single Page Application)와 MPA(Multi Page Application)
SPA(Single Page Application)
개념
- 1개의 HTML 파일로 구성
- 페이지 이동 시 새로운 HTML을 요청하지 않고, 자바스크립트를 사용해 필요한 부분만 동적으로 로딩하여 컨텐츠를 갱신하는 방식
특징
- 페이지 이동 시 전체 페이지가 다시 로드되지 않아 더 빠르게 반응한다. (빠른 사용자 경험(UX))
- 대부분의 렌더링이 클라이언트 측에서 이루어진다. (CSR)
- 첫 로딩 시 모든 자바스크립트 파일을 다운로드해야 해서 초기 로딩 속도가 느릴 수 있다. (초기 로딩 속도 느림)
- 처음에는 검색 엔진 크롤러가 컨텐츠를 제대로 인식하지 못할 수 있다. (SEO 최적화 어려움)
MPA(Multi Page Application)
개념
- 페이지를 이동할 때마다 새로운 HTML 페이지를 서버(Server)에서 받아와서 렌더링하는 방식
특징
- 각 페이지 요청 시마다 서버에서 HTML을 생성하여 클라이언트로 전달한다. (SSR)
- 색 엔진이 페이지를 쉽게 크롤링할 수 있어 SEO 최적화에 유리하다. (SEO에 유리)
- 각 페이지가 필요한 리소스만 불러오므로, 초기 로딩 시간이 빠르다. (초기 로딩 속도 빠름)
- 페이지를 전환할 때마다 전체 페이지가 다시 로드되기 때문에 SPA에 비해 느리게 느껴질 수 있다.
비교
CSR, SSR
기능 | CSR(Client Side Rendering) | SSR(Server Side Rendering) |
초기 로딩 속도 | 느림 (JS 로딩 및 렌더링 필요) | 빠름 (HTML 미리 렌더링) |
SEO | 제한적 | 우수 |
서버 부하 | 낮음 | 높음 |
페이지 전환 속도 | 빠름 (클라이언트에서 처리) | 느림 (서버 요청 필요) |
사용자 경험 | 첫 로딩 속도 느림, 전환 시 속도 빠름 | 첫 로딩 속도 빠름, 전환 시 속도 느림 |
CSR, SSR, SSG, ISR
구분 | CSR (Client Side Rendering) |
SSR (Server Side Rendering) |
SSG (Static Site Generation) |
ISR (Incremental Static Regeneration) |
사용 함수 | @useEffect@ @useState@ |
@getServerSideProps@ | @getStaticProps@ | @getStaticProps@ + @revalidate@ 옵션 |
렌더링 시점 | 클라이언트에서 실행 시 렌더링 | 요청 시 서버에서 렌더링 | 빌드 시 정적 파일 생성 | 빌드 시 정적 파일 생성 + 요청 시 일정 주기로 재생성 |
초기 로딩 속도 |
느림 (JS 다운로드 후 렌더링) |
빠름 (서버에서 미리 렌더링) |
매우 빠름 (정적 파일 제공) |
빠름 (정적 파일 제공, 주기적 업데이트) |
SEO | 나쁨 (JS 의존도 높음) |
좋음 (HTML 완성 형태 제공) |
좋음 (HTML 완성 형태 제공) |
좋음 (정적 페이지 제공 + 업데이트 가능) |
데이터 최신성 |
실시간 (최신 데이터 가능) |
요청 시 최신 데이터 | 정적 (빌드 시점 데이터 고정) |
일정 주기로 최신 데이터 업데이트 |
SPA/MPA | SPA | SPA / MPA | SPA | SPA |
사용 예 | SPA, 대시보드 | 블로그, 마케팅 페이지 | 블로그, 문서 사이트 | 이커머스, 블로그 (자주 변경되는 페이지) |
CSR은 초기 로딩이 느리지만, 이후 페이지 전환 속도가 매우 빠르며 SPA(Single Page Application)에서 주로 사용한다.
SSR은 서버에서 HTML을 완성해서 보내기 때문에 SEO에 유리하고 초기 로딩 속도가 빠르다. 클라이언트에서 요청할 때마다 서버에서 렌더링하는 방식이다.
SSG는 빌드 시 정적 HTML을 생성해두므로 요청 시 빠르게 응답할수 있으나, 데이터 변경 시 다시 빌드를 해줘야 한다.
ISR은 SSG의 장점(빠른 로딩)과 SSR의 장점(데이터 최신성)을 결합한 방식으로, 정적 페이지를 일정 주기로 재생성해 최신 데이터를 반영하는 방법이다.
SEO와 최신 데이터가 중요한 경우 SSR 방식을, 성능과 빠른 로딩이 중요한 경우에는 SSG 또는 ISR 방식을, 사용자 인터랙션이 많은 페이지의 경우 CSR 방식을 사용하면 좋다.
참고 사이트
728x90
728x90
'Framework > Next.js' 카테고리의 다른 글
[Next.js] <Link> 컴포넌트 클릭 시, 최상단으로 스크롤 되는 현상 막는 방법 (0) | 2024.12.20 |
---|---|
[Next.js] Hydration 에러 해결하는 방법 (Next.js 15) (0) | 2024.11.21 |
[Next.js] 테마 토글 기능 설정하기 (with shadcn/ui) (0) | 2024.11.05 |
[Next.js] 갑자기 "'next'은(는) 내부 또는 외부 명령, 실행할 수 있는 프로그램, 또는배치 파일이 아닙니다." 오류가 발생할 때 해결 방법 (0) | 2024.10.30 |
[Next.js] 환경 변수 사용 방법 (1) | 2024.10.29 |
[Next.js] 폴더 구조 및 동적 경로 설정하기 (0) | 2024.10.16 |
[Next.js] 정적 생성(Static Generation)과 서버사이드 렌더링(Server-side Rendering) (0) | 2024.08.08 |
[Next.js] 메타데이터(Metadata) 추가하기 (0) | 2024.08.07 |