클라이언트 사이드 랜더링 (CSR) vs. 서버 사이드 랜더링 (SSR)
1. 클라이언트 사이드 랜더링 (CSR)
CSR(Client-Side Rendering)은 사용자의 브라우저에서 페이지가 로드되는 방식으로, 서버는 기본적인 HTML 구조만 제공하고, 나머지 페이지의 콘텐츠는 브라우저에서 자바스크립트로 동적으로 생성됩니다. CSR의 핵심 아이디어는 브라우저에서 페이지의 인터페이스를 렌더링하는 작업을 맡기고, 클라이언트가 처음에 HTML, CSS, 자바스크립트를 다운로드한 후에 모든 콘텐츠를 로컬에서 처리하는 것입니다.
1.1 동작 방식
- 초기 요청: 사용자가 웹사이트에 접속하면 서버는 기본적인 HTML 파일을 제공하고, 이 파일에는 자바스크립트 파일을 로드하는 스크립트 태그만 포함되어 있습니다.
- 클라이언트 처리: 브라우저는 이 자바스크립트를 실행하여 콘텐츠를 렌더링합니다. 이 과정에서 자바스크립트는 API를 호출하거나 다른 비동기 작업을 통해 데이터를 받아오고, 이 데이터를 HTML 요소로 변환하여 페이지에 표시합니다.
- 초기 로드 속도: 초기 로드 시 시간이 조금 더 소요될 수 있습니다. 왜냐하면 자바스크립트를 다운로드하고 실행한 후에야 콘텐츠가 완전히 표시되기 때문입니다.
- 빠른 상호작용: 초기 로드 후 페이지의 상호작용성은 매우 빠릅니다. 페이지의 일부분만 업데이트하거나 변경하는 경우 전체 페이지를 다시 로드할 필요가 없습니다.
// App.js
import React, { useEffect, useState } from 'react';
const App = () => {
const [data, setData] = useState(null);
useEffect(() => {
// 클라이언트에서 API 호출
fetch('https://api.example.com/data')
.then((response) => response.json())
.then((data) => setData(data));
}, []);
return (
<div>
<h1>Client-Side Rendering Example</h1>
{data ? <pre>{JSON.stringify(data, null, 2)}</pre> : <p>Loading...</p>}
</div>
);
};
export default App;
CSR은 클라이언트에서 데이터를 비동기적으로 가져와 렌더링합니다.
1.2 CSR의 장점
- 빠른 상호작용: 자바스크립트를 통해 비동기적으로 데이터만 업데이트하여 페이지를 다시 로드하지 않고도 빠르게 반응할 수 있습니다.
- 동적 애플리케이션에 적합: React, Vue.js 같은 SPA(Single Page Application) 프레임워크를 사용하면 동적인 사용자 인터페이스를 쉽게 구축할 수 있습니다.
1.3 CSR의 단점
- 초기 로드 속도: 초기 페이지 로드가 느릴 수 있습니다. 특히 사용자의 네트워크 속도가 느릴 경우 자바스크립트 파일의 다운로드와 실행까지 시간이 걸리기 때문입니다.
- SEO 최적화 어려움: 초기 HTML 파일에 콘텐츠가 거의 포함되지 않기 때문에 검색 엔진 크롤러가 웹사이트의 콘텐츠를 제대로 인식하지 못할 수 있습니다.
2. 서버 사이드 랜더링 (SSR)
SSR(Server-Side Rendering)은 서버에서 HTML을 미리 렌더링하여 클라이언트에 전송하는 방식입니다. 이 방식은 브라우저가 HTML을 다운로드할 때 이미 서버에서 모든 콘텐츠가 준비된 상태로 제공되기 때문에, 초기 로드 시간이 빨라질 수 있습니다.
2.1 동작 방식
- 초기 요청: 사용자가 웹사이트에 접속하면 서버는 사용자가 요청한 데이터와 함께 완전한 HTML 페이지를 생성하여 브라우저에 전달합니다.
- 브라우저 처리: 브라우저는 이 HTML을 바로 렌더링하여 화면에 표시합니다. 이후 추가적인 상호작용을 위해 자바스크립트가 필요한 경우, 브라우저가 자바스크립트를 다운로드하고 실행할 수 있습니다.
- 빠른 초기 로드: SSR은 초기 페이지 로드가 빠릅니다. 서버에서 이미 콘텐츠가 완전히 준비된 상태로 전송되므로, 브라우저는 HTML 파일을 받아 바로 렌더링할 수 있습니다.
// pages/index.js
import React from 'react';
const Home = ({ data }) => {
return (
<div>
<h1>Server-Side Rendering Example</h1>
<pre>{JSON.stringify(data, null, 2)}</pre>
</div>
);
};
// SSR을 위한 데이터 fetching
export async function getServerSideProps() {
const res = await fetch('https://api.example.com/data');
const data = await res.json();
return {
props: {
data,
},
};
}
export default Home;
SSR은 서버에서 요청할 때마다 페이지를 렌더링합니다.
2.2 SSR의 장점
- 빠른 초기 로드 속도: 서버에서 이미 콘텐츠를 준비한 후 전송하므로 페이지의 첫 번째 렌더링 시간이 빠릅니다.
- SEO에 유리: 검색 엔진 크롤러가 처음 HTML 파일을 크롤링할 때 이미 모든 콘텐츠가 포함되어 있으므로, SEO에 유리합니다.
2.3 SSR의 단점
- 서버 부하: 모든 페이지 요청마다 서버가 HTML을 생성해야 하기 때문에 서버에 부하가 걸릴 수 있습니다. 특히 많은 사용자가 접속할 경우 서버의 성능이 저하될 수 있습니다.
- 페이지 상호작용성: 사용자가 페이지에서 추가적인 상호작용을 시도할 때, 자바스크립트를 새로 다운로드하고 실행해야 하는 경우가 있을 수 있어 상호작용성이 느려질 수 있습니다.
CSR 와 SSR 비교
| 클라이언트 사이드 랜더링 (CSR) | 서버 사이드 랜더링 (SSR) | |
| 상호작용성 | 매우 빠름 | 자바스크립트 로드 후 상호작용 가능 |
| 서버 부하 | 서버 부하는 적음 | 서버 부하가 많을 수 있음 |
| SEO 최적화 | SEO에 불리할 수 있음 | SEO에 유리 |
| 초기 로드 시간 | 느릴 수 있음 | 빠름 |
하이브리드 접근 방식
현대의 웹 애플리케이션에서는 CSR과 SSR의 장점을 모두 취하는 하이브리드 방식이 자주 사용됩니다.
3.Static Site Generation (SSG)
3.1 SSG의 개념
SSG는 빌드 시점에 모든 페이지를 정적 HTML 파일로 생성하는 방식입니다. 한 번 생성된 페이지는 서버 요청이 있을 때마다 매번 서버에서 HTML을 동적으로 생성하지 않고, 이미 만들어진 정적 파일을 반환하기 때문에 페이지 로드 속도가 매우 빠릅니다.
3.2 동작 방식
- 빌드 시점 렌더링: 개발자가 애플리케이션을 빌드할 때 모든 페이지가 미리 렌더링되고, 이 HTML 파일들이 CDN(Content Delivery Network)이나 서버에 배포됩니다.
- 정적 파일 제공: 사용자가 웹사이트를 요청할 때 서버는 이미 준비된 HTML 파일을 제공하므로 응답 시간이 짧습니다.
- 데이터 업데이트: SSG는 주로 정적 콘텐츠에 적합합니다. 콘텐츠 업데이트를 위해서는 빌드 과정을 다시 거쳐야 하며, 모든 페이지를 다시 렌더링해야 합니다.
// pages/index.js
import React from 'react';
const Home = ({ data }) => {
return (
<div>
<h1>Static Site Generation Example</h1>
<pre>{JSON.stringify(data, null, 2)}</pre>
</div>
);
};
// SSG를 위한 데이터 fetching
export async function getStaticProps() {
const res = await fetch('https://api.example.com/data');
const data = await res.json();
return {
props: {
data,
},
};
}
export default Home;
SSG는 빌드 시점에 모든 페이지를 정적으로 생성합니다.
3.3 SSG의 장점
- 빠른 로드 속도: 미리 렌더링된 HTML 파일을 사용하기 때문에 매우 빠르게 페이지를 로드할 수 있습니다.
- SEO 친화적: 모든 페이지가 정적 HTML로 제공되기 때문에 검색 엔진 크롤러가 웹사이트의 콘텐츠를 쉽게 인식하고 색인할 수 있습니다.
- 서버 부하 최소화: 서버는 요청마다 HTML 파일을 생성할 필요가 없기 때문에 서버 부하가 매우 낮습니다.
3.4 SSG의 단점
- 동적 콘텐츠 제한: 정적 사이트로 생성되기 때문에 콘텐츠가 자주 변경되는 웹사이트에 적합하지 않습니다. 콘텐츠를 업데이트하려면 빌드 과정이 필요하여 즉각적인 변경이 어렵습니다.
- 큰 규모의 웹사이트: 페이지 수가 많아지면 빌드 시간이 길어질 수 있으며, 빌드 후 모든 정적 파일을 배포하는 데 많은 시간이 걸릴 수 있습니다.
3.5 SSG 사용 사례
- 블로그나 마케팅 웹사이트처럼 콘텐츠 업데이트가 빈번하지 않은 웹사이트에서 주로 사용됩니다.
- 콘텐츠가 고정된 상태로 사용자에게 빠르게 전달되어야 하는 페이지들에 적합합니다.
4. Incremental Static Regeneration (ISR)
4.1 ISR의 개념
ISR은 SSG의 한계를 극복하기 위해 등장한 개념입니다. SSG와 마찬가지로 빌드 시점에 페이지를 정적으로 생성하지만, 특정 페이지에 대해 요청이 있을 때마다 서버가 그 페이지를 다시 생성(재생성)하는 기능을 추가적으로 제공합니다. 이 방식은 Next.js에서 지원되며, 정적 페이지와 동적 콘텐츠를 결합할 수 있는 유연한 방식입니다.
4.2 동작 방식
- 초기 빌드: SSG와 같이 처음 빌드할 때 정적 HTML 페이지를 생성하여 서버 또는 CDN에 배포합니다.
- 재생성 주기 설정: 개발자는 페이지별로 revalidate라는 설정을 통해 일정 주기로 해당 페이지를 다시 생성할 수 있도록 합니다. 예를 들어, revalidate: 60으로 설정하면 페이지는 60초마다 한 번씩 새로 렌더링됩니다.
- 동적 콘텐츠 업데이트: 지정된 재생성 주기 동안에는 기존 정적 파일을 그대로 제공하고, 설정된 시간이 지나면 서버는 해당 페이지를 다시 생성해 최신 데이터를 반영한 HTML 파일을 만들어 다음 요청 시 제공할 수 있습니다.
// pages/index.js
import React from 'react';
const Home = ({ data }) => {
return (
<div>
<h1>Incremental Static Regeneration Example</h1>
<pre>{JSON.stringify(data, null, 2)}</pre>
</div>
);
};
// ISR을 위한 데이터 fetching
export async function getStaticProps() {
const res = await fetch('https://api.example.com/data');
const data = await res.json();
return {
props: {
data,
},
revalidate: 60, // 60초마다 페이지를 재생성
};
}
export default Home;
ISR은 SSG의 장점을 유지하면서도 일정 주기로 페이지를 다시 생성하여 최신 데이터를 반영합니다.
4.3 ISR의 장점
- 정적 페이지의 속도: 여전히 정적 사이트처럼 매우 빠른 로드 속도를 제공합니다.
- 동적 콘텐츠 처리: 특정 페이지나 데이터를 일정 시간마다 업데이트할 수 있기 때문에 콘텐츠가 자주 변경되는 웹사이트에도 적합합니다.
- 유연한 SEO 최적화: 페이지가 재생성될 때마다 최신 데이터를 반영할 수 있어 SEO에도 유리합니다.
4.4 ISR의 단점
- 복잡성 증가: 빌드된 페이지를 다시 재생성하는 로직이 추가되므로 서버 관리와 최적화에 신경 써야 합니다.
- 정확한 실시간 데이터 제공의 어려움: 지정된 재생성 주기 동안에는 구식 데이터를 제공할 가능성이 있습니다. 예를 들어, 사용자가 업데이트된 데이터를 즉시 확인하고자 할 때 그 주기가 지나기 전이라면 이전 데이터를 받을 수 있습니다.
4.5 ISR 사용 사례
- 뉴스 사이트처럼 콘텐츠가 자주 업데이트되지만, 정적 파일로도 제공 가능한 경우 매우 유용합니다.
- 이커머스 웹사이트처럼 일부 동적 콘텐츠(재고, 가격 등)만 주기적으로 업데이트되는 사이트에서 많이 활용됩니다.
SSG와 ISR의 비교
| Static Site Generation (SSG) | Incremental Static Regeneration (ISR) | |
| 페이지 재생성 주기 | 재생성이 필요 없음 | 지정된 시간 주기로 페이지가 재생성됨 |
| 동적 콘텐츠 지원 | 제한적 | 가능, 지정된 주기로 동적 콘텐츠 업데이트 |
| 서버 부하 | 서버 부하가 거의 없음 | 재생성 시 서버 부하 발생 가능 |
| 초기 빌드 시간 | 빌드 시 모든 페이지가 생성됨 | 빌드 시 일부 페이지만 생성됨 |
CSR, SSR,SSG, ISR의 비교 요약
| CSR | SSR | SSG | ISR | |
| 초기 로드 시간 | 느림 | 빠름 | 매우 빠름 | 매우 빠름 |
| 상호작용성 | 매우 빠름 | 느릴 수 있음 | 자바스크립트 실행 후 상호작용 가능 | 자바스크립트 실행 후 상호작용 가능 |
| 서버 부하 | 낮음 | 높음 | 거의 없음 | 재생성 시 서버 부하 발생 가능 |
| SEO | SEO에 불리할 수 있음 | SEO에 매우 유리 | SEO에 매우 유리 | SEO에 유리 |
| 동적 콘텐츠 | 매우 유리 | 유리 | 제한적 | 유리 |
| 사용 사례 | 실시간 상호작용이 필요한 SPA | 콘텐츠가 자주 변하지 않는 페이지 | 정적 블로그, 마케팅 웹사이트 | 동적 콘텐츠를 포함한 이커머스, 뉴스 사이트 |
'개발 공부' 카테고리의 다른 글
| 라이브러리와 프레임워크 (3) | 2024.10.12 |
|---|---|
| 모놀리식 아키텍처 / 마이크로 서비스 아키텍처 (1) | 2024.10.10 |
| URL의 정의와 기본 개념 (9) | 2024.10.06 |
| HTML5 (1) | 2024.10.06 |
| RxJS: firstValueFrom()과 lastValueFrom()의 차이와 사용법 (0) | 2024.09.24 |