๊ฐ๋
์์ฝ
- CSR (Client-Side Rendering): ๋ธ๋ผ์ฐ์ ๊ฐ JS๋ก ์ฑ์ ์ด๊ธฐํํ๊ณ ๋ ๋๋ง.
- SSR (Server-Side Rendering): ์๋ฒ๊ฐ HTML์ ๋ง๋ค์ด ์ ๋ฌํ๊ณ , ํด๋ผ์ด์ธํธ์์ ํ์ด๋๋ ์ด์
.
๋์ ํ๋ฆ ๊ฐ๋จ ๋น๊ต
- CSR: HTML ๊ณจ๊ฒฉ โ JS ๋ฒ๋ค ๋ก๋ โ ๋ฐ์ดํฐ ํ์นญ โ ํด๋ผ์ด์ธํธ ๋ ๋.
- SSR: ์์ฒญ ์ ์๋ฒ์์ ๋ฐ์ดํฐ ํ์นญ/๋ ๋ โ ์์ฑ๋ HTML ์๋ต โ ํ์ด๋๋ ์ด์
.
์ฅ๋จ์ ์ ๋ฆฌ
- CSR ์ฅ์
- ๋ผ์ฐํ
์ ํ์ด ๋น ๋ฅด๊ณ ํ๋ถํ ์ธํฐ๋์
์ ์ ๋ฆฌ.
- CDN ๋ฐฐํฌ๊ฐ ์ฝ๊ณ ์๋ฒ ๋ถ๋ด์ด ์ ์.
- ๋ณต์กํ ํด๋ผ์ด์ธํธ ์ํ ๊ด๋ฆฌ์ ๊ถํฉ์ด ์ข์.
- CSR ๋จ์
- ์ด๊ธฐ ๋ก๋๊ฐ ๋๋ฆด ์ ์๊ณ JS ์์กด๋๊ฐ ํผ.
- ๊ธฐ๋ณธ SEO์ ๋ถ๋ฆฌ(์ฌ์ ๋ ๋๊ฐ ์์).
- SSR ์ฅ์
- ์ด๊ธฐ ํ์(First Paint/TTFB ์ดํ)๊ฐ ๋น ๋ฅด๊ณ SEO์ ์ ๋ฆฌ.
- ์ ์ฌ์/์ ์ฑ๋ฅ ๊ธฐ๊ธฐ์์๋ ์ต์ด ์ฒด๊ฐ์ด ์ข์.
- SSR ๋จ์
- ์๋ฒ ๋ถํ ์ฆ๊ฐ, ์บ์ฑ/์ค์ผ์ผ ์ ๋ต ํ์.
- ์์ฒญ๋ง๋ค ๋ ๋ โ TTFB ์ฆ๊ฐ ๊ฐ๋ฅ.
Next.js ๊ด์ ์์์ ์ ํ
- SSG/ISR: ๋น๋ ํ์(SSG) ํน์ ์ฃผ๊ธฐ์ ์ฌ์์ฑ(ISR)์ผ๋ก ์ฑ๋ฅ๊ณผ SEO๋ฅผ ๋ชจ๋ ํ๋ณด.
- App Router(Server/Client Components)
- ์๋ฒ ์ปดํฌ๋ํธ๊ฐ ๊ธฐ๋ณธ(SSR๋ก ๋ฐ์ดํฐ ๊ฐ๊น์ด). ํด๋ผ์ด์ธํธ ์ํ/์ด๋ฒคํธ๊ฐ ํ์ํ ๋ถ๋ถ๋ง
use client๋ก ๋ถ๋ฆฌ.
- ๋ฐ์ดํฐ ํจ์นญ
- ์๋ฒ ์ปดํฌ๋ํธ:
fetch() ๊ธฐ๋ณธ ์บ์/์ฌ๊ฒ์ฆ ์ต์
์ผ๋ก ISR ์ ์ฌ ํจ๊ณผ.
- ํด๋ผ์ด์ธํธ ์ปดํฌ๋ํธ:
useEffect/SWR/React Query ๋ฑ์ผ๋ก CSR ํจํด.
์ฝ๋ ์์
- SSR(์๋ฒ ์ปดํฌ๋ํธ, Next.js App Router)
// app/articles/page.tsx (Server Component)
export default async function Page() {
const res = await fetch("https://api.example.com/articles", {
cache: "no-store",
});
const articles = await res.json();
return (
<main>
<h1>Articles</h1>
<ul>
{articles.map((a: any) => (
<li key={a.id}>{a.title}</li>
))}
</ul>
</main>
);
}
- CSR(ํด๋ผ์ด์ธํธ ์ปดํฌ๋ํธ)
"use client";
import { useEffect, useState } from "react";
export default function Page() {
const [data, setData] = useState<any[] | null>(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
fetch("/api/items")
.then((r) => r.json())
.then((d) => setData(d))
.finally(() => setLoading(false));
}, []);
if (loading) return <div>Loading...</div>;
return (
<ul>
{data?.map((item) => (
<li key={item.id}>{item.name}</li>
))}
</ul>
);
}
์ด๋ค ๊ฑธ ์ ํํ ๊น? (์ฒดํฌ๋ฆฌ์คํธ)
- SEO๊ฐ ์ค์ํ๊ฐ? โ SSR/SSG/ISR ์ฐ์ ๊ณ ๋ ค.
- ์ค์๊ฐ ๊ฐ์ธํ, ์ฌ์ฉ์๋ณ ๋ฐ์ดํฐ๊ฐ ๋ง๋? โ SSR+ํด๋ผ์ด์ธํธ ์ํ ํผํฉ ๋๋ ์์ CSR.
- ์ด๊ธฐ ๋ก๋ ์๊ฐ์ด ์ค์ํ ๋๋ฉ/๋ง์ผํ
ํ์ด์ง์ธ๊ฐ? โ SSG/ISR.
- ๋ณต์กํ ์ธํฐ๋์
/์คํ๋ผ์ธ ๊ธฐ๋ฅ ์ค์ฌ์ธ๊ฐ? โ CSR ๋๋ ํ์ด๋ธ๋ฆฌ๋.
๊ฒฐ๋ก
- ๋จ์ผ ํด๋ฒ์ ์๋ค. ๊ณต๊ฐ ํ์ด์ง๋ SSR/SSG๋ก, ์ฑ ๋ด๋ถ๋ CSR๋ก ๊ตฌ์ฑํ๋ ํ์ด๋ธ๋ฆฌ๋๊ฐ ํ์ค์ ์ธ ์ต์ ํด๋ค.
- Next.js App Router์์๋ ์๋ฒ/ํด๋ผ์ด์ธํธ ์ปดํฌ๋ํธ๋ฅผ ์์ด ์ฌ์ฉํ๋ฉฐ, ์บ์/์ฌ๊ฒ์ฆ ์ ๋ต์ผ๋ก ์ฑ๋ฅยทSEOยท๊ฐ๋ฐ ์์ฐ์ฑ์ ํจ๊ป ๊ฐ์ ธ๊ฐ ์ ์๋ค.