08. ๐ Next.js App Router์ ์๋ฒ ์ปดํฌ๋ํธ
๐ ๊ฐ์
React Server Components(RSC)์ ์ฒ ํ๊ณผ App Router ์ํคํ ์ฒ๋ฅผ ํตํด ํ๋์ ์ธ ๋ ๋๋ง ์ ๋ต์ ๋ง์คํฐํฉ๋๋ค.
๐ ์ด ๋ฉด์ ํญ๋ชฉ์ ๋ชฉํ
โฑ๏ธ ์์ ์ฝ๊ธฐ ์๊ฐ: 26๋ถ (ํต์ฌ ์์ฝ: 13๋ถ)
๐บ๏ธ ์ด ์ฑํฐ์ ํ๋ฆ
[๊ฐ๋
์ฌ์ ] โ [์ง๋ฌธ 1: App Router & RSC] โ [์ง๋ฌธ 2: ๋ ๋๋ง ์ ๋ต SSR/SSG/ISR] โ [์ค์ ๋ณํ ์ง๋ฌธ]
๐ฏ ์ด ์ฑํฐ๋ฅผ ๋ค ์ฝ์ผ๋ฉด ํ ์ ์๋ ๊ฒ
- ์๋ฒ ์ปดํฌ๋ํธ(RSC)์ ํด๋ผ์ด์ธํธ ์ปดํฌ๋ํธ์ ์ฐจ์ด์ ์ฌ์ฉ ์์ ์ ๊ตฌ๋ถํฉ๋๋ค.
App Routerํ๊ฒฝ์์ ๋ฐ์ดํฐ ํ์นญ๊ณผ ์บ์ฑ์ด ์ด๋ป๊ฒ ๋ณํ๋์ง ์ค๋ช ํฉ๋๋ค.- ๋น์ฆ๋์ค ์๊ตฌ์ฌํญ์ ๋ฐ๋ผ SSR, SSG, ISR ์ค ์ต์ ์ ๋ ๋๋ง ๋ฐฉ์์ ์ ํํฉ๋๋ค.
๐ ํต์ฌ ๊ฐ๋ ์ฌ์ (Concept Glossary)
1. ๋ฆฌ์กํธ ์๋ฒ ์ปดํฌ๋ํธ (React Server Components, RSC)
์๋ฒ ๋๋ ๋น๋ ํ๊ฒฝ์์ ์คํ๋์ด ๋ ๋๋ง ๊ฒฐ๊ณผ๊ฐ RSC Payload๋ก ์ ๋ฌ๋๋ ์ปดํฌ๋ํธ์ ๋๋ค. ์ปดํฌ๋ํธ ์ฝ๋๊ฐ ํด๋ผ์ด์ธํธ ๋ฒ๋ค์ ํฌํจ๋์ง ์์ผ๋ฏ๋ก ๋ธ๋ผ์ฐ์ ๊ฐ ๋ค์ด๋ก๋ํ๊ณ ํ์ด๋๋ ์ด์ ํด์ผ ํ JavaScript๋ฅผ ์ค์ผ ์ ์์ผ๋ฉฐ, ์๋ฒ ํ๊ฒฝ์ ๋ฐ์ดํฐ ์์ค์ ์ง์ ์ ๊ทผํ ์ ์์ต๋๋ค.
2. ํ์ด๋๋ ์ด์ (Hydration)
์๋ฒ์์ ๋ง๋ค์ด์ง ์ ์ HTML ์์ ์๋ฐ์คํฌ๋ฆฝํธ๋ฅผ ์ ํ ์ด๋ฒคํธ ๋ฆฌ์ค๋๋ฅผ ๋ฌ๊ณ ์ธํฐ๋ํฐ๋ธํ ์ํ๋ก ๋ง๋๋ '๋ถํ' ๊ณผ์ ์ ๋๋ค. RSC๋ ํ์ด๋๋ ์ด์ ์ด ํ์ ์๋ ๋ถ๋ถ์ด ๋์ด๋๋ค๋ ์ ์ด ํต์ฌ์ ๋๋ค.
3. ISR (Incremental Static Regeneration)
๋น๋ ์์ ์ ์ ์ ํ์ด์ง๋ฅผ ์์ฑ(SSG)ํ๋, ์ผ์ ์๊ฐ์ด ์ง๋๋ฉด ๋ฐฑ๊ทธ๋ผ์ด๋์์ ํด๋น ํ์ด์ง๋ฅผ ์๋ก ์์ฑํ์ฌ ์ ๋ฐ์ดํธํ๋ ๋ฐฉ์์ ๋๋ค. '์ ์ ํ์ด์ง์ ์ฑ๋ฅ'๊ณผ '๋ฐ์ดํฐ์ ์ค์๊ฐ์ฑ'์ ๋ชจ๋ ์ก์ ์ ๋ต์ ๋๋ค.
๐บ๏ธ ์ด ๋ฌธ์์ ๋ฐฐ๊ฒฝ ์ธ๊ณ๊ด: '์์๋ค ์ปค๋ฎค๋ํฐ'
- ๐ฃ ์์ฒ (ํ๋ฐ): "์ํธ ๋! '์์๋ค ๋ฉ์ธ ํ์ด์ง'์์ ๋ ์ง ํฌ๋งท, ๋งํฌ๋ค์ด ๋ณํ, ์ถ์ฒ ๊ธ ๊ณ์ฐ์ ๋ค ํด๋ผ์ด์ธํธ์์ ์ฒ๋ฆฌํ๋๋ ์ด๊ธฐ ๋ก๋ฉ์ด ๋๋ฆฝ๋๋ค. ๊ทธ๋ฐ๋ฐ ๊ธฐ๋ฅ์ ๋นผ๊ธฐ๋ ์ด๋ ต์ต๋๋ค."
- ๐ฆ ์ํธ (๋ฆฌ๋): "์์ฒ ๋, ํด๋ผ์ด์ธํธ๊ฐ ๊ทธ ์ผ์ ๋ชจ๋ ๋งก์ ํ์๋ ์์ด์. ์๋ฒ ์ปดํฌ๋ํธ(RSC)๋ฅผ ์ฐ๋ฉด ๋ฌด๊ฑฐ์ด ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋ฐ์ดํฐ ๊ฐ๊ณต์ ์๋ฒ์ ๋จ๊ธฐ๊ณ , ๋ธ๋ผ์ฐ์ ์๋ ์ฌ์ฉ์๊ฐ ์ํธ์์ฉํด์ผ ํ๋ ์์ ๊ฒฝ๊ณ๋ง ๋ณด๋ผ ์ ์์ต๋๋ค."
๋ฉด์ ์ง๋ฌธ 1. ๋ฆฌ์กํธ ์๋ฒ ์ปดํฌ๋ํธ(RSC)์ ํด๋ผ์ด์ธํธ ์ปดํฌ๋ํธ์ ๊ฒฐ์ ์ ์ธ ์ฐจ์ด์, ๊ฐ๊ฐ ์ธ์ ์ฌ์ฉํด์ผ ํ๋์ง ์ค๋ช ํด ๋ณด์ธ์.
๐ฏ ์ถ์ ์๋
๋ชจ๋ ๋ฆฌ์กํธ์ ๊ฐ์ฅ ํฐ ํจ๋ฌ๋ค์ ๋ณํ์ธ '์๋ฒ ์ธก ์คํ'์ ์ดํดํ๊ณ ์๋์ง, ๊ทธ๋ฆฌ๊ณ ํด๋ผ์ด์ธํธ ๋ฒ๋ค ํฌ๊ธฐ๋ฅผ ์ต์ ํํ๋ ค๋ ์ํคํ ์ฒ์ ๊ณ ๋ฏผ์ด ์๋์ง ํ์ธํฉ๋๋ค.
๐ฃ ์์ฒ ์ด์ Naive ๊ตฌํ (Bad Case)
์์ฒ ์ด๋ ์๋ฌ๋ฅผ ๋นจ๋ฆฌ ์์ ๊ธฐ ์ํด ๋ชจ๋ ํ์ผ ์ต์๋จ์ 'use client'๋ฅผ ๋ถ์ด๊ณ ์์ต๋๋ค.
'use client'; // ๐ฃ ์์ฒ : "์ด๊ฒ ์์ผ๋ฉด ๋ค ์๋ฌ ๋๋๋ผ๊ณ ์. ๊ทธ๋ฅ ๋ค ํด๋ผ์ด์ธํธ ์ปดํฌ๋ํธ๋ก ํ๋ฉด ์ ๋๋์?"
import { format } from 'date-fns'; // โ ๏ธ ๊ฑฐ๋ํ ๋ ์ง ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ํด๋ผ์ด์ธํธ ๋ฒ๋ค์ ํฌํจ๋จ
export function PostItem({ post }) {
// ๋ณ๋ค๋ฅธ ์ธํฐ๋์
(onClick ๋ฑ)์ด ์๋๋ฐ๋ ํด๋ผ์ด์ธํธ ์ปดํฌ๋ํธ๋ก ์ ์ธํจ
return <div>{format(new Date(post.createdAt), 'yyyy-MM-dd')}</div>;
}๐ฆ ์ํธ์ ๋ฆฌ๋ทฐ ํฌ์ธํธ
"์์ฒ ๋,'use client'๋ ํด๋ผ์ด์ธํธ ๋ฒ๋ค ๊ฒฝ๊ณ๋ฅผ ์ฌ๋ ์ ์ธ์ ๋๋ค.onClick,useState,window์ฒ๋ผ ๋ธ๋ผ์ฐ์ ์คํ์ด ํ์ํ ๋ถ๋ถ์๋ง ๋๊ณ , ๋ฐ์ดํฐ ๊ฐ๊ณต์ด๋ ๋ฌด๊ฑฐ์ด ๋ผ์ด๋ธ๋ฌ๋ฆฌ ํ์ฉ์ ์๋ฒ์์ ๋๋ด๋ ํธ์ด RSC์ ์ฅ์ ์ ์ด๋ฆฝ๋๋ค."
๐ฆ ์ํธ์ ์ํคํ ์ฒ ๊ฐ์ด๋ (Good Case)
์ํธ ๋ฆฌ๋๊ฐ ์๋ฒ์ ํด๋ผ์ด์ธํธ์ ํ์ ๊ตฌ์กฐ๋ฅผ ๋ณด์ฌ์ค๋๋ค.
// app/posts/PostList.jsx
// ๐ฆ ์ํธ: "์๋ฒ๋ ๋ฐ์ดํฐ๋ฅผ ์ค๋นํ๊ณ , ํด๋ผ์ด์ธํธ๋ ์ํธ์์ฉ๋ง ๋ด๋นํ๊ฒ ๋๋๋๋ค."
// ๐ข Server Component (๊ธฐ๋ณธ๊ฐ)
// - DB ์ง์ ์ ๊ทผ ๊ฐ๋ฅ
// - ๊ฑฐ๋ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ(date-fns ๋ฑ)๋ฅผ ์จ๋ ํด๋ผ์ด์ธํธ์๊ฒ ์ ์ก ์ ๋จ!
async function PostList() {
const posts = await db.post.findMany(); // โ
์๋ฒ๋๊น ์ง์ fetch!
return (
<div>
{posts.map(post => (
<PostItem key={post.id} post={post} />
))}
</div>
);
}// app/posts/LikeButton.jsx
// ๐ฑ Client Component ('use client')
// - ์ธํฐ๋์
์ด ํ์ํ ๋ถ๋ถ๋ง ์ต์ํํ์ฌ ๋ถ๋ฆฌ
'use client';
function LikeButton() {
const [liked, setLiked] = useState(false);
return <button onClick={() => setLiked(!liked)}>์ข์์</button>;
}'use client'๋ ํ์ผ ๋จ์ ๊ฒฝ๊ณ์
๋๋ค. ํ ํ์ผ์ ์ ์ธํ๋ฉด ๊ทธ ํ์ผ์ด importํ๋ ๋ชจ๋๋ ํด๋ผ์ด์ธํธ ๋ฒ๋ค์ ํฌํจ๋ ์ ์์ผ๋ฏ๋ก, ์ํธ์์ฉ์ด ํ์ํ leaf ์ปดํฌ๋ํธ ๊ทผ์ฒ์ ์ต๋ํ ์ข๊ฒ ๋๋ ๊ฒ์ด ์ข์ต๋๋ค.
๐ ๋ ๋ฒจ๋ณ ๋ต๋ณ ๊ฐ์ด๋ (Self-Check)
- Level 1 (Junior): "์๋ฒ ์ปดํฌ๋ํธ๋ ์๋ฒ์์ ์คํ๋๊ณ , ํด๋ผ์ด์ธํธ ์ปดํฌ๋ํธ๋ ๋ธ๋ผ์ฐ์ ์์ ์คํ๋ฉ๋๋ค. ํ (useState ๋ฑ)์ ์ฐ๋ ค๋ฉด ํด๋ผ์ด์ธํธ ์ปดํฌ๋ํธ๋ฅผ ์จ์ผ ํฉ๋๋ค."
- Level 2 (Senior): "ํด๋ผ์ด์ธํธ ๋ฒ๋ค ์ฌ์ด์ฆ(Zero-bundle size) ๊ด์ ์์์ ์ด์ ์ ์ค๋ช ํฉ๋๋ค. ์๋ฒ ์ปดํฌ๋ํธ๋ ๋ณด์์ ๋ฏผ๊ฐํ ์ ๋ณด๋ฅผ ์จ๊ธธ ์ ์๊ณ ์๋ฒ ์์์ ํ์ฉํด ๋ฐ์ดํฐ ํ์นญ์ ๊ฐ์ํํ ์ ์์์ ๊ฐ์กฐํฉ๋๋ค. ๋ํ ๋ ์ปดํฌ๋ํธ ๊ฐ์ '์ง๋ ฌํ(Serialization)' ์ ์ฝ ์กฐ๊ฑด์ ์ธ๊ธํฉ๋๋ค."
- Level 3 (Specialist): "RSC ํ์ด๋ก๋(Payload)์ ๊ตฌ์กฐ๋ฅผ ๋ถ์ํ๊ณ , ํ์ด๋๋ ์ด์ ๋น์ฉ์ ์ค์ด๋ ๋ฉ์ปค๋์ฆ์ ์ค๋ช ํฉ๋๋ค. 'Boundary'๋ฅผ ์ด๋ป๊ฒ ์ค์ ํ๋๋์ ๋ฐ๋ผ ์ฌ์ฉ์ ๊ฒฝํ(LCP ๋ฑ)์ด ์ด๋ป๊ฒ ๋ณํ๋์ง ์ค์ ํ๋ก์ ํธ ๊ฒฝํ์ ๋ฐํ์ผ๋ก ๋ ผ๋ฆฌ์ ์ผ๋ก ๋ถ์ํฉ๋๋ค."
๋ฉด์ ์ง๋ฌธ 2. SSR, SSG, ISR์ ์ฐจ์ด์ ์ ์ค๋ช ํ๊ณ , ์๋น์ค์ ์ฑ๊ฒฉ์ ๋ฐ๋ผ ์ด๋ค ์ ๋ต์ ์ ํํ ์ง ๊ธฐ์ค์ ์ ์ํด ๋ณด์ธ์.
๐ฏ ์ถ์ ์๋
๋ค์ํ ๋ ๋๋ง ์ ๋ต์ ์ฅ๋จ์ ์ ๋น์ฆ๋์ค ์ํฉ์ ๋งคํํ ์ ์๋ ์ค๋ฌด ๋ฅ๋ ฅ์ ํ์ธํฉ๋๋ค. ์ฑ๋ฅ(Speed)๊ณผ ์ต์ ์ฑ(Freshness) ์ฌ์ด์ ํธ๋ ์ด๋์คํ๋ฅผ ์ดํดํ๋์ง๊ฐ ํต์ฌ์ ๋๋ค.
๐ฃ ์์ฒ ์ด์ Naive ๊ตฌํ (Bad Case)
์์ฒ ์ด๋ '๊ฒ์ ์์ง ์ต์ ํ(SEO)'๊ฐ ์ค์ํ๋ค๊ณ ํด์ ๋ชจ๋ ํ์ด์ง๋ฅผ SSR๋ก ๊ตฌํํ์ต๋๋ค.
// ๐ฃ ์์ฒ : "์๋ฒ์์ ๋ค ๊ทธ๋ ค์ ์ฃผ๋๊น ํญ์ SSR์ด ์ข์ ๊ฑฐ ์๋๊ฐ์?"
export async function getServerSideProps() { // โ ๏ธ Pages Router ๋ฐฉ์์ ์์ฒญ๋ณ SSR ์์
const data = await fetchLargeData();
return { props: { data } };
}
// โ ๏ธ ๋ฌธ์ : ์ฌ์ฉ์๊ฐ ์ ์ํ ๋๋ง๋ค ์๋ฒ๊ฐ ๋งค๋ฒ ํฐ ๋ฐ์ดํฐ๋ฅผ ํ์นญํ๋๋ผ
// ์๋ต ์๋(TTFB)๊ฐ ๋๋ ค์ง๊ณ ์๋ฒ ๋น์ฉ์ด ํฌ๊ฒ ๋์ด๋จ๐ฆ ์ํธ์ ๋ฆฌ๋ทฐ ํฌ์ธํธ
"์์ฒ ๋, ์ ๋ณํ๋ ํ์ด์ง๋ฅผ ์ ๋งค๋ฒ ์๋ก ๊ทธ๋ฆฌ๋์? ์ ์ ํ์ด์ง(SSG)๋ก ๋ฏธ๋ฆฌ ๊ตฌ์๋๋ฉด CDN์ ํ๊ณ ๋น์ ์๋๋ก ์ ๋ฌ๋ ํ ๋ฐ ๋ง์ด์ฃ . SSR์ '๋๋ง์ ์ํ ๋ฐ์ดํฐ'๊ฐ ์์ ๋๋ง ์ฐ๋ ๋๊ตฌ์์."
๐ฆ ์ํธ์ ์ํคํ ์ฒ ๊ฐ์ด๋ (Good Case)
์ํธ ๋ฆฌ๋๊ฐ ์ํฉ๋ณ ์ต์ ๋ ๋๋ง ๋งคํธ๋ฆญ์ค๋ฅผ ์ ์ํฉ๋๋ค.
// ๐ฆ ์ํธ: "์ฌ์ฉ์๋ณ๋ก ๋ฌ๋ผ์ง๋์ง, ์ผ๋ง๋ ์์ฃผ ๋ฐ๋๋์ง ๋จผ์ ๋ณด์ธ์."
// 1. SSG (Static Site Generation): ์๋น์ค ์๊ฐ, ๋ธ๋ก๊ทธ ๊ธ
// - ๋น๋ ์์ ์ ๋ฑ ํ ๋ฒ ์์ฑ. ๊ฐ์ฅ ๋น ๋ฆ.
export const dynamic = 'force-static';
// 2. ISR (Incremental Static Regeneration): ์ผํ๋ชฐ ์ํ ๋ชฉ๋ก, ์ค์๊ฐ์ฑ ๊ด๊ณ
// - ์ ์ ํ์ด์ง์ ์ฅ์ ์ ๊ฐ์ง๋ฉด์๋ ์ผ์ ์๊ฐ๋ง๋ค ์๋ ๊ฐฑ์ .
export const revalidate = 60; // 60์ด๋ง๋ค ๊ฐฑ์
// 3. SSR (Server Side Rendering): ๋ง์ดํ์ด์ง, ์ฅ๋ฐ๊ตฌ๋
// - ์ฌ์ฉ์๋ง๋ค ๊ฒฐ๊ณผ๊ฐ ๋ค๋ฅผ ๋. ์ต์ ์ฑ 100% ๋ณด์ฅ.
export const dynamic = 'force-dynamic';๐ ๋ ๋ฒจ๋ณ ๋ต๋ณ ๊ฐ์ด๋ (Self-Check)
- Level 1 (Junior): "SSR์ ์ ์ํ ๋๋ง๋ค ์๋ฒ๊ฐ ๊ทธ๋ฆฌ๊ณ , SSG๋ ๋น๋ํ ๋ ๋ฏธ๋ฆฌ ๋ง๋ญ๋๋ค. ISR์ ์ฃผ๊ธฐ์ ์ผ๋ก ๋ค์ ๋ง๋ญ๋๋ค."
- Level 2 (Senior): "๊ฐ ์ ๋ต์ด ์น ์งํ(Core Web Vitals) ์ค ํนํ TTFB์ LCP์ ์ด๋ค ์ํฅ์ ์ฃผ๋์ง ์ค๋ช ํฉ๋๋ค. ๋ฐ์ดํฐ์ ์ค์๊ฐ์ฑ๊ณผ ์๋ฒ ๋ถํ ๊ฐ์ ํธ๋ ์ด๋์คํ๋ฅผ ๊ณ ๋ คํ์ฌ ์ ๋ต์ ์ ํํ๋ ๋ ผ๋ฆฌ๋ฅผ ์ ์ํฉ๋๋ค."
- Level 3 (Specialist): "App Router์์์ 'Full Route Cache'์ 'Request Memoization' ๊ฐ๋ ์ ์ฐ๊ฒฐํฉ๋๋ค. ๋จ์ํ ํ์ด์ง ๋จ์์ ์ ๋ต์ ๋์ด, ํ๋์ ํ์ด์ง ์์์ ํน์ ์ปดํฌ๋ํธ๋ ISR๋ก, ์ด๋ค ๋ถ๋ถ์ Streaming์ ํตํ SSR๋ก ๊ตฌ์ฑํ๋ 'ํ์ด๋ธ๋ฆฌ๋ ์ํคํ ์ฒ' ์ค๊ณ ์ญ๋์ ๋ณด์ฌ์ค๋๋ค."
๐ ์ค์ ๋ณํ ์ง๋ฌธ (Related Variations)
๋ฉด์ ์ง๋ฌธ 112. Next.js์ 'Streaming'๊ณผ 'Suspense'๊ฐ ์ฌ์ฉ์ ๊ฒฝํ์ ๊ฐ์ ํ๋ ์๋ฆฌ๋ ๋ฌด์์ธ๊ฐ์?
- ๐ฏ ์ถ์ ์๋: ๋ฐ์ดํฐ ํ์นญ์ด ์๋ฃ๋ ๋๊น์ง ์ ์ฒด ํ์ด์ง ๋ ๋๋ง์ ์ฐจ๋จํ์ง ์๊ณ , ๋น์ด์๋ ํ๋ฉด์ ์ต์ ํํ๋ ๊ธฐ์ ์ ํ์ธํฉ๋๋ค.
- ๐ก ํต์ฌ ์๋ฆฌ & ๋ต๋ณ: ๊ธฐ์กด SSR์ ๋ฐ์ดํฐ๊ฐ ๋ชจ๋ ์ค๋น๋ ๋๊น์ง ์ฌ์ฉ์์๊ฒ ๋น ํ๋ฉด๋ง ๋ณด์ฌ์ฃผ๊ธฐ ์ฌ์ ์ง๋ง(All-or-nothing), ์คํธ๋ฆฌ๋ฐ์ ์ค๋น๋ ๋ถ๋ถ(๋ฐ์ดํฐ๊ฐ ํ์ ์๋ ์ ์ ๋ ์ด์์ ๋ฑ)๋ถํฐ ๋จผ์ ๋ธ๋ผ์ฐ์ ์ ์ ์กํฉ๋๋ค. ๋๋ฆฐ ์ปดํฌ๋ํธ๋
Suspense๋ฐ์ด๋๋ฆฌ๋ก ๊ฐ์ธ ์ค์ผ๋ ํค UI๋ฅผ ๋ณด์ฌ์ฃผ๊ณ , ๋ฐ์ดํฐ๊ฐ ๋์ฐฉํ๋ ๋๋ก ํด๋น ๋ถ๋ถ์ ์ ์ง์ ์ผ๋ก ์ ๋ฌํฉ๋๋ค. ์ด๋ ์ฌ์ฉ์์๊ฒ ํ์ด์ง๊ฐ ๋ ๋นจ๋ฆฌ ๋ฐ์ํ๋ค๋ ๋๋(Perceived Performance)์ ์ค๋๋ค.
๋ฉด์ ์ง๋ฌธ 120. next/image ์ปดํฌ๋ํธ๊ฐ ๋จ์ํ <img> ํ๊ทธ๋ณด๋ค ๋์ ์ด์ ๋ ๋ฌด์์ธ๊ฐ์?
- ๐ฏ ์ถ์ ์๋: ์ด๋ฏธ์ง ์ต์ ํ๋ผ๋ ๊ตฌ์ฒด์ ์ธ ์ฑ๋ฅ ๊ฐ์ ๋๊ตฌ์ ๋ด๋ถ ๋์์ ์ดํดํ๊ณ ์๋์ง ํ์ธํฉ๋๋ค.
- ๐ก ํต์ฌ ์๋ฆฌ & ๋ต๋ณ: ์ฒซ์งธ, ์๋ ์ด๋ฏธ์ง ์ต์ ํ์ ๋๋ค. ์ฌ์ฉ์์ ๊ธฐ๊ธฐ์ ๋ง์ถฐ WebP ๊ฐ์ ํ๋์ ์ธ ํฌ๋งท์ผ๋ก ๋ณํํ๊ณ ํฌ๊ธฐ๋ฅผ ๋ฆฌ์ฌ์ด์งํฉ๋๋ค. ๋์งธ, Lazy Loading์ ๊ธฐ๋ณธ ์ ์ฉํ์ฌ ํ๋ฉด์ ๋ณด์ด์ง ์๋ ์ด๋ฏธ์ง๋ ๋์ค์ ๋ก๋ฉํฉ๋๋ค. ์ ์งธ, Layout Shift ๋ฐฉ์ง์ ๋๋ค. ์ด๋ฏธ์ง ๋ก๋ฉ ์ ์๋ ์ ํํ ์๋ฆฌ๋ฅผ ํ๋ณดํ์ฌ LCP์ CLS ์งํ๋ฅผ ๊ฐ์ ํฉ๋๋ค. ๋ง์ง๋ง์ผ๋ก CDN ์บ์ฑ์ ํตํด ์๋ณธ ์๋ฒ์ ๋ถํ๋ฅผ ์ค์ฌ์ค๋๋ค.
๋ฉด์ ์ง๋ฌธ 135. ๋ฏธ๋ค์จ์ด(Middleware)๋ฅผ ํ์ฉํ์ฌ ํด๊ฒฐํ ์ ์๋ ์ค๋ฌด์ ์ธ ์ฌ๋ก๋ฅผ ๋ค์ด๋ณด์ธ์.
- ๐ฏ ์ถ์ ์๋: ์์ฒญ๊ณผ ์๋ต ์ฌ์ด์ ๊ณตํต ๋ก์ง์ ํจ์จ์ ์ผ๋ก ์ฒ๋ฆฌํ๋ ๊ฐ๋ก์ฑ๊ธฐ(Interceptor) ํจํด์ ํ์ธํฉ๋๋ค.
- ๐ก ํต์ฌ ์๋ฆฌ & ๋ต๋ณ: ๊ฐ์ฅ ๋ํ์ ์ธ ์ฌ๋ก๋ **์ธ์ฆ ๋ฐ ๊ถํ ์ฒดํฌ(Auth Guard)**์ ๋๋ค. ๋ก๊ทธ์ธ์ด ๋์ง ์์ ์ฌ์ฉ์๊ฐ ๋ณดํธ๋ ํ์ด์ง์ ์ ๊ทผํ ๋ ๋ ๋๋ง์ด ์์๋๊ธฐ๋ ์ ์ ๋ฆฌ๋ค์ด๋ ํธ ์ํฌ ์ ์์ต๋๋ค. ๋ํ ์ฌ์ฉ์์ ๊ตญ๊ฐ ์ ๋ณด์ ๋ฐ๋ฅธ ๊ตญ์ ํ(i18n) ๋ผ์ฐํ , A/B ํ ์คํธ๋ฅผ ์ํ ์ฟ ํค ๊ธฐ๋ฐ ๋ถ๊ธฐ ์ฒ๋ฆฌ, ํน์ ๋ด ์ฐจ๋จ๊ณผ ๊ฐ์ ๋ณด์ ๋ก์ง์ ํ์ด์ง ๋ ๋๋ง ์ฑ๋ฅ์ ์ํฅ์ ์ฃผ์ง ์์ผ๋ฉด์ ์ ์ญ์ ์ผ๋ก ์ฒ๋ฆฌํ ์ ์์ต๋๋ค.
๐ ๋ง๋ฌด๋ฆฌ ํด์ฆ
Q1. 'use client'๋ฅผ ๋ชจ๋ ์ปดํฌ๋ํธ์ ๋ถ์ด๋ ๋ฐฉ์์ด ์ RSC ๊ด์ ์์ ์ข์ง ์์๊ฐ์?
โ
์ ๋ต: ์๋ฒ์์ ๋๋ผ ์ ์๋ ๋ฐ์ดํฐ ์กฐํ์ ๋ฌด๊ฑฐ์ด ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊น์ง ํด๋ผ์ด์ธํธ ๋ฒ๋ค๋ก ๋ณด๋ด ์ด๊ธฐ JS ๋น์ฉ์ ํค์ฐ๊ธฐ ๋๋ฌธ
๐ก ์์ธ ํด์ค:
- ์๋ฆฌ ์ค๋ช : ์๋ฒ ์ปดํฌ๋ํธ์ ๊ธฐ๋ณธ ๊ฐ์น๋ ๋ธ๋ผ์ฐ์ ์ ๋ณด๋ผ ์ผ์ ์ค์ด๋ ๊ฒ์ ๋๋ค. DB ์ ๊ทผ, ๋ฐ์ดํฐ ๊ฐ๊ณต, ๋ฌด๊ฑฐ์ด ๋ชจ๋ ์ฌ์ฉ์ ์๋ฒ์์ ๋๋ด๊ณ , ์ํธ์์ฉ์ด ํ์ํ ์์ ๊ฒฝ๊ณ๋ง ํด๋ผ์ด์ธํธ๋ก ๋๊ธฐ๋ ๊ฒ์ด ํต์ฌ์ ๋๋ค.
- ์ค๋ต ํผ๋๋ฐฑ: ์๋ฌ๊ฐ ์ฌ๋ผ์ง๋ค๋ ์ด์ ๋ก
'use client'๋ฅผ ๋ํ๋ฉด, ๋ฌธ์ ํด๊ฒฐ์ด ์๋๋ผ ์๋ฒ/ํด๋ผ์ด์ธํธ ์ฑ ์ ๊ฒฝ๊ณ๋ฅผ ๋ฌด๋๋จ๋ฆฐ ๊ฒ์ ๋๋ค. - ๐ ํต์ฌ ๊ธฐ์ต๋ฒ: ํด๋ผ์ด์ธํธ ์ปดํฌ๋ํธ๋ ๊ธฐ๋ณธ๊ฐ์ด ์๋๋ผ ํ์ํ ๊ฒฝ๊ณ์ ๋๋ค.
Q2. App Router์์ layout, page, loading, error ํ์ผ์ ์ดํดํด์ผ ํ๋ ์ด์ ๋ ๋ฌด์์ธ๊ฐ์?
โ
์ ๋ต: ๋ผ์ฐํธ ์ธ๊ทธ๋จผํธ๋ง๋ค ๋ฐ์ดํฐ, UI ๊ณตํต ๊ตฌ์กฐ, ์คํธ๋ฆฌ๋ฐ, ์๋ฌ ๋ณต๊ตฌ ๊ฒฝ๊ณ๋ฅผ ๋๋ ์ ์๊ธฐ ๋๋ฌธ
๐ก ์์ธ ํด์ค:
- ์๋ฆฌ ์ค๋ช : App Router๋ ๋จ์ ํ์ผ ๋ผ์ฐํ ์ด ์๋๋ผ UI์ ๋ฐ์ดํฐ ๋ก๋ฉ์ ๊ฒฝ๊ณ๋ฅผ ํ์ผ ์์คํ ์ผ๋ก ํํํฉ๋๋ค. ๋ฉด์ ์์๋ ์ด ๊ตฌ์กฐ๊ฐ UX์ ์ฅ์ ๊ฒฉ๋ฆฌ๋ฅผ ์ด๋ป๊ฒ ๊ฐ์ ํ๋์ง ๋งํด์ผ ํฉ๋๋ค.
- ์ค๋ต ํผ๋๋ฐฑ:
pagesํด๋์ ์ด๋ฆ๋ง ๋ค๋ฅธ ๋ผ์ฐํ ๋ฐฉ์์ด๋ผ๊ณ ๋ตํ๋ฉด RSC์ streaming์ ์ฅ์ ์ ๋์นฉ๋๋ค. - ๐ ํต์ฌ ๊ธฐ์ต๋ฒ: App Router์ ํ์ผ์ URL๋ณด๋ค UI ๊ฒฝ๊ณ๋ฅผ ๋ ๋ง์ด ์ค๋ช ํฉ๋๋ค.
Q3. ์์ฒ ์ด์ ํ ์คํธ ํ์: ๊ฒ์๊ธ ๋ชฉ๋ก์ ์๋ฒ ์ปดํฌ๋ํธ, ์ข์์ ๋ฒํผ์ ํด๋ผ์ด์ธํธ ์ปดํฌ๋ํธ๋ก ๋๋ ์ด์ ๋ ๋ฌด์์ธ๊ฐ์?
โ
์ ๋ต: ๋ชฉ๋ก ๋ฐ์ดํฐ ์กฐํ์ ๋ ๋๋ง์ ์๋ฒ์์ ์ฒ๋ฆฌํ๊ณ , ํด๋ฆญ ์ํ์ ์ด๋ฒคํธ ํธ๋ค๋ฌ๊ฐ ํ์ํ ์ต์ ๋ถ๋ถ๋ง ํด๋ผ์ด์ธํธ๋ก ๋ณด๋ด๊ธฐ ์ํด์
๐ก ์์ธ ํด์ค:
- ์๋ฆฌ ์ค๋ช : RSC์ ์ค๊ณ ํ๋จ์ "๋ฌด์์ด ๋ธ๋ผ์ฐ์ ์์ ๊ผญ ์คํ๋์ด์ผ ํ๋๊ฐ"๋ฅผ ๋ฌป๋ ์ผ์ ๋๋ค. ์ํธ์์ฉ์ด ์๋ ๋ฐ์ดํฐ UI๋ ์๋ฒ์ ๋จ๊ธฐ๊ณ , ์ด๋ฒคํธ๊ฐ ํ์ํ leaf๋ง ํด๋ผ์ด์ธํธ๋ก ๋ณด๋ ๋๋ค.
- ์ค๋ต ํผ๋๋ฐฑ: ํ๋์ ํ์ด์ง๋ผ์ ์ ๋ถ ๊ฐ์ ์คํ ํ๊ฒฝ์ ์์ด์ผ ํ๋ค๋ ์๊ฐ์ ์๋ฒ/ํด๋ผ์ด์ธํธ ์ปดํฌ๋ํธ ๋ชจ๋ธ๊ณผ ๋ง์ง ์์ต๋๋ค.
- ๐ ํต์ฌ ๊ธฐ์ต๋ฒ: ๋ธ๋ผ์ฐ์ ์๋ ์ฌ์ฉ์๊ฐ ๋ง์ง๋ ๋ถ๋ถ๋ง ์ต๋ํ ์๊ฒ ๋ณด๋ ๋๋ค.
๐ฃ ์์ฒ ์ด์ ํด๊ทผ ์ผ๊ธฐ
์ค๋์ 'use client'๊ฐ ๋ฌธ์ ํด๊ฒฐ ์ฃผ๋ฌธ์ด ์๋๋ผ ๋น์ฉ์ด ๋ถ๋ ๊ฒฝ๊ณ ์ ์ธ์ด๋ผ๋ ๊ฑธ ๋ฐฐ์ ๋ค. ์์ ๊ฐ์ผ๋ฉด ์๋ฌ๊ฐ ๋๋ฉด ์ผ๋จ ๋ถ์ด๊ณ ๋ดค์ ํ
๋ฐ, ์ด์ ๋ ์ด ์ปดํฌ๋ํธ๊ฐ ์ ๋ง ๋ธ๋ผ์ฐ์ ์์ ์คํ๋์ด์ผ ํ๋์ง ๋จผ์ ๋ฌผ์ด๋ด์ผ ํ๋ค.
๐ก "์๋ฒ ์ปดํฌ๋ํธ์ ํต์ฌ์ ์ ๊ธฐ๋ฅ์ ๋ํ๋ ๊ฒ ์๋๋ผ, ๋ธ๋ผ์ฐ์ ๊ฐ ํ์ง ์์๋ ๋๋ ์ผ์ ๋์ด๋ด๋ ๊ฒ์ด๋ค."
๋ค์ ์ค๊ณ์์๋ page, layout, loading, error๋ฅผ ๋จ์ ํ์ผ๋ช ์ผ๋ก ๋ณด์ง ์๊ณ ์ฌ์ฉ์ ๊ฒฝํ์ ๊ฒฝ๊ณ๋ก ๋ด์ผ๊ฒ ๋ค. ์์ฒ ์ด ์ด์ "์ด๋์ ์ฝ๋๋ฅผ ๋๊น"๋ณด๋ค "์ด๋์ ์คํ๋์ด์ผ ํ ๊น"๋ฅผ ๋จผ์ ๋ฌป๊ธฐ ์์ํ๋ค.