๐Ÿš€ Next.js 3์žฅ: App Router์˜ 3๋Œ€ ๋ Œ๋”๋ง ์ „๋žต (SSR, SSG, ISR)

2026๋…„ 4์›” 30์ผ ์ˆ˜์ •๋จ

๐Ÿ“‹ ๊ฐœ์š”

SSR, SSG, ISR ์„ธ ๊ฐ€์ง€ ๋ Œ๋”๋ง ์ „๋žต์˜ ์ฐจ์ด์™€ App Router์—์„œ ๊ฐ๊ฐ์„ ์–ธ์ œ ์จ์•ผ ํ•˜๋Š”์ง€ ์•Œ์•„๋ด…๋‹ˆ๋‹ค.

๐Ÿ“‹ ๋ชฉ์ฐจ


๐Ÿ“Œ ์ด ๋ฌธ์„œ๋ฅผ ์ฝ๊ธฐ ์ „์—

โฑ๏ธ ์˜ˆ์ƒ ์ฝ๊ธฐ ์‹œ๊ฐ„: 20๋ถ„(์ „์ฒด) / ํ•ต์‹ฌ ํŒŒํŠธ๋งŒ: 10๋ถ„

๐Ÿ—บ๏ธ ์ด ๋ฌธ์„œ์˜ ํ๋ฆ„
๋ Œ๋”๋ง ์‹œ์  ๋‘ ๊ฐ€์ง€ โ†’ ์ •์  ๋ Œ๋”๋ง(SSG) โ†’ ๋™์  ๋ Œ๋”๋ง(SSR) โ†’ ์ ์ง„์  ์žฌ์ƒ์„ฑ(ISR) โ†’ ๋นŒ๋“œ ๊ฒฐ๊ณผ ๊ฟ€ํŒ(์˜์ˆ˜๋„ค ์ปค๋ฎค๋‹ˆํ‹ฐ ์˜ˆ์ œ)

๐ŸŽฏ ์ด ๋ฌธ์„œ๋ฅผ ๋‹ค ์ฝ์œผ๋ฉด ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ

  • ๊ฐ ํ™”๋ฉด ์„ฑ๊ฒฉ๊ณผ ์„œ๋น„์Šค ์š”๊ตฌ์‚ฌํ•ญ์— ๋งž์ถฐ ์ตœ์ ์˜ ์„œ๋ฒ„ ๋ Œ๋”๋ง ๋ฐฉ์‹์„ ์Šค์Šค๋กœ ์„ค๊ณ„ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ๋นŒ๋“œ ๋กœ๊ทธ๋ฅผ ํ†ตํ•ด ์ฝ”๋“œ๊ฐ€ ์˜๋„์น˜ ์•Š๊ฒŒ ์„œ๋ฒ„ ์ž์›์„ ๊ณ ๊ฐˆ์‹œํ‚ค๊ณ  ์žˆ์ง€ ์•Š์€์ง€ ํ†ต์ œํ•  ์ˆ˜ ์žˆ๋‹ค.

๐Ÿ—บ๏ธ ์ด ๋ฌธ์„œ์˜ ๋ฐฐ๊ฒฝ ์„ธ๊ณ„๊ด€: '์˜์ˆ˜๋„ค ์ปค๋ฎค๋‹ˆํ‹ฐ'

  • ์˜์ฒ (์ƒˆ๋กœ ์˜จ ์ฃผ๋‹ˆ์–ด): "์–ด? ๋ถ„๋ช…ํžˆ ๋กœ์ปฌ์—์„œ๋Š” ์ž˜ ๋๋Š”๋ฐ... ๋ฐฐํฌํ•˜๊ณ  ๋‚˜๋‹ˆ๊นŒ ํšŒ์‚ฌ ์†Œ๊ฐœ ํŽ˜์ด์ง€ ํ•˜๋‚˜ ์—ด ๋•Œ๋งˆ๋‹ค ์„œ๋ฒ„๊ฐ€ ๋น„๋ช…์„ ์งˆ๋Ÿฌ์š”! ๐Ÿ˜ญ"
  • ์˜ํ˜ธ(FE ๋ฆฌ๋“œ): "์˜์ฒ  ๋‹˜... ์†Œ๊ฐœ ํŽ˜์ด์ง€ ์ตœ์ƒ๋‹จ์— cookies() ํ•จ์ˆ˜๋ฅผ ๋„ฃ์œผ์…จ๋”๊ตฐ์š”. ๊ทธ ํ•œ ์ค„ ๋•Œ๋ฌธ์— ์ •์ ์œผ๋กœ ๊ตฌ์›Œ์ ธ์•ผ ํ•  ํŽ˜์ด์ง€๊ฐ€ ์‹ค์‹œ๊ฐ„ ํ–„๋ฒ„๊ฑฐ๊ฐ€ ๋œ ๊ฑฐ์˜ˆ์š”!"

๐Ÿค” ์™œ ์•Œ์•„์•ผ ํ•˜๋Š”๊ฐ€

์˜์ˆ˜๋„ค ์ปค๋ฎค๋‹ˆํ‹ฐ์— ๋“œ๋””์–ด ์œ ์ž…์ž๊ฐ€ ๋ชฐ๋ฆฌ๊ธฐ ์‹œ์ž‘ํ–ˆ์–ด.

์˜์š• ๋„˜์น˜๋Š” ์˜์ฒ (์ƒˆ๋กœ ์˜จ ์ฃผ๋‹ˆ์–ด) ๋‹˜์€ ๋ฌด์ฒ™ ๊ธฐ๋ปค์ง€๋งŒ, ๊ธฐ์จ๋„ ์ž ์‹œ. ์Šคํ„ฐ๋”” ๋งค์นญ ์•ฑ์˜ "์†Œ๊ฐœ ํŽ˜์ด์ง€(/about)" ํ•˜๋‚˜ ๋ณด๋ ค๊ณ  ๋“ค์–ด์˜จ ์œ ์ €๋“ค ๋•Œ๋ฌธ์— DB ์„œ๋ฒ„ CPU๊ฐ€ 100%๋ฅผ ์ฐ์œผ๋ฉฐ ์ „์ฒด ์„œ๋น„์Šค๊ฐ€ ๋งˆ๋น„๋˜์–ด ๋ฒ„๋ ธ์–ด.

์˜์ˆ˜(PM/๋ฐฑ์—”๋“œ) ๋‹˜์ด ์šธ์ƒ์„ ์ง€์œผ๋ฉฐ ๋‹ฌ๋ ค์™”์–ด. "์•„๋‹ˆ, ์ผ ๋…„ ๋‚ด๋‚ด ๊ธ€์ž ํ•˜๋‚˜ ์•ˆ ๋ณ€ํ•˜๋Š” ํšŒ์‚ฌ ์†Œ๊ฐœ ํŽ˜์ด์ง€์— ์ ‘์†ํ•  ๋•Œ ๋งˆ๋‹ค ์™œ ์ด๋Ÿฐ ๊ณผ๋„ํ•œ ๋ถ€ํ•˜๊ฐ€ ๊ฑธ๋ฆฌ๋Š” ๊ฑฐ์ฃ ? ๋Œ€์ฒด ์„œ๋ฒ„์—์„œ ๊ตญ๋ฐฅ์„ ์ƒˆ๋กœ ๋“์ด๋Š” ์ด์œ ๊ฐ€ ๋ญก๋‹ˆ๊นŒ!"

๋ฒ”์ธ์€ ์ด๋ฒˆ์—๋„ ์˜์ฒ  ๋‹˜. ๊ทธ๋Š” ์ฟ ํ‚ค ๊ธฐ๋ฐ˜ ๋‹ค๊ตญ์–ด ์ฒ˜๋ฆฌ๋ฅผ ํ•œ๋‹ต์‹œ๊ณ  ์ตœ์ƒ์œ„ ์˜์—ญ์— cookies() ํ•จ์ˆ˜๋ฅผ ์ตœ์ƒ์œ„์— ๋„ฃ์—ˆ๊ณ , ์ด๋กœ ์ธํ•ด Next.js๊ฐ€ ๋ฏธ๋ฆฌ ์•„์ฃผ ๋ง›์žˆ๊ฒŒ ๊ตฌ์›Œ๋‘์—ˆ๋˜(Static) ํŽ˜์ด์ง€๋“ค์„ ๋ชจ์กฐ๋ฆฌ ๋Ÿฐํƒ€์ž„ ์ฆ‰์„ ๋ Œ๋”๋ง(Dynamic)์œผ๋กœ ๊ฐ•๋“ฑ์‹œ์ผœ๋ฒ„๋ฆฐ ๊ฑฐ์•ผ. ๋ Œ๋”๋ง ์ „๋žต์„ ์ œ๋Œ€๋กœ ๋ชจ๋ฅด๋ฉด ์ด๋Ÿฐ '์„œ๋ฒ„ ๋ถ€ํ•˜ ๋ฌธ์ œ'์„ ๋งŒ๋“ค๊ฒŒ ๋ผ.


๐Ÿ—๏ธ ๋น„์œ ๋กœ ๋จผ์ € ์ดํ•ดํ•˜๊ธฐ

๐Ÿง’ 5์‚ด์—๊ฒŒ ์„ค๋ช…ํ•œ๋‹ค๋ฉด? (์˜์ˆ˜๋„ค ๊ตญ๋ฐฅ์ง‘)

๋ Œ๋”๋ง ์ „๋žต์€ ์Œ์‹์„ ๋งŒ๋“ค์–ด๋‘๋Š” ํƒ€์ด๋ฐ ์˜ ์ฐจ์ด์•ผ.

  1. Static Rendering (SSG): ์ƒˆ๋ฒฝ ์žฅ์‚ฌ ์ „(๋นŒ๋“œ ํƒ€์ž„)์— ๋Œ€ํ˜• ๊ฐ€๋งˆ์†ฅ์— ๊ตญ๋ฐฅ์„ ์‹น ๋‹ค ๋“์—ฌ๋‘๋Š” ๊ฑฐ์•ผ. ์†๋‹˜์ด ์˜ค๋ฉด 1์ดˆ ๋งŒ์— ํˆญ ๋˜์ ธ์ค˜. ์ œ์ผ ๋น ๋ฅด๊ณ  ์•Œ๋ฐ”์ƒ(์„œ๋ฒ„)๋„ ์•ˆ ํž˜๋“ค์–ด. (ํšŒ์‚ฌ ์†Œ๊ฐœ, ๋ธ”๋กœ๊ทธ)
  2. Dynamic Rendering (SSR): ์ด๊ฑด ์ฆ‰์„์—์„œ ๋ณถ๋Š” ์ œ์œก๋ณถ์Œ ์ด์•ผ. ์†๋‹˜์ด ์ฃผ๋ฌธ(์ ‘์†)ํ•  ๋•Œ๋งˆ๋‹ค ์•Œ๋ฐ”์ƒ์ด ๋ถˆ ์ผœ๊ณ  ๊ณ ๊ธฐ๋ฅผ ์ƒˆ๋กœ ๋ณถ์•„. ์„œ๋ฒ„๊ฐ€ ๊ณ ์ƒํ•˜์ง€๋งŒ, "์ „ ๋น„๊ณ„ ๋นผ์ฃผ์„ธ์š”(๊ฐœ์ธํ™” ์ฟ ํ‚ค)" ๊ฐ™์€ ์š”๊ตฌ๋ฅผ 100% ๋งž์ถฐ ์ค„ ์ˆ˜ ์žˆ์–ด. (๋งˆ์ดํŽ˜์ด์ง€, ์žฅ๋ฐ”๊ตฌ๋‹ˆ)
  3. ISR (Incremental Static Regeneration): "์ผ์ • ์‹œ๊ฐ„๋งˆ๋‹ค ์ƒˆ๋กœ ๋ฌด์ณ ๋‚˜์˜ค๋Š” ๊ฒ‰์ ˆ์ด" ๊ฐ™์€ ๊ฑฐ์•ผ. ๋ฏธ๋ฆฌ ๋ฌด์ณ๋‘์ง€๋งŒ, 10๋ถ„๋งˆ๋‹ค ์ฃผ๋ฐฉ์—์„œ ์ƒˆ ๊ฑธ๋กœ ๋ฌด์ณ์„œ ์ฑ„์›Œ ๋„ฃ์–ด. ์‹ ์„ ํ•จ๊ณผ ์†๋„๋ฅผ ๋‹ค ์žก๋Š” ๋ฐฉ๋ฒ•์ด์ง€.

๐Ÿ›‘ ๋ Œ๋”๋ง ์‹œ์ ์˜ ๋น„๋ฐ€: Build-time vs Run-time ๐ŸŸข

๐ŸŽฏ ์ด ์„น์…˜ ์ดํ›„์— ๋‹น์‹ ์€:

  • ๋นŒ๋“œ ํƒ€์ž„๊ณผ ๋Ÿฐํƒ€์ž„์˜ ๊ธฐ์ˆ ์  ์ฐจ์ด๋ฅผ ๋ช…ํ™•ํžˆ ๊ตฌ๋ถ„ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ์™œ ๋นŒ๋“œ ํƒ€์ž„ ์ตœ์ ํ™”๊ฐ€ ์„œ๋ฒ„ ๋น„์šฉ ์ ˆ๊ฐ์˜ ํ•ต์‹ฌ์ธ์ง€ ์ดํ•ดํ•œ๋‹ค.

๊ฐ€์žฅ ํ•ต์‹ฌ์ด ๋˜๋Š” ๊ธฐ์ค€์€ ๊ฒฐ๊ตญ "HTML์„ ๋„๋Œ€์ฒด ์–ธ์ œ ๋งŒ๋“œ๋А๋ƒ?" ์•ผ.

  1. Build Time (๋นŒ๋“œ ํƒ€์ž„): ๊ฐœ๋ฐœ์ž๊ฐ€ ์„œ๋ฒ„์— ์ฝ”๋“œ ๋ฐฐํฌํ•˜๋ ค๊ณ  npm run build ๋ฅผ ์ณค์„ ๋•Œ.(์‚ฌ์šฉ์ž 0๋ช…)
  2. Run Time (๋Ÿฐํƒ€์ž„): ๋นŒ๋“œ ๋๋‚ด๊ณ  ์šด์˜ ์ค‘์ผ ๋•Œ, ์‚ฌ์šฉ์ž๊ฐ€ ์šฐ๋ฆฌ ์•ฑ ๋„๋ฉ”์ธ ์น˜๊ณ  ์ ‘์†ํ•œ ๋ฐ”๋กœ ๊ทธ ์ˆœ๊ฐ„.

๐Ÿงฉ 1. Static Rendering (๊ณผ๊ฑฐ์˜ SSG) ๐ŸŸข

๐ŸŽฏ ์ด ์„น์…˜ ์ดํ›„์— ๋‹น์‹ ์€:

  • Static Rendering์ด ๊ธฐ๋ณธ๊ฐ’(Default)์œผ๋กœ ๋™์ž‘ํ•˜๋Š” ์›๋ฆฌ๋ฅผ ์•ˆ๋‹ค.
  • ์–ด๋–ค ์ฝ”๋“œ๊ฐ€ Static ์ตœ์ ํ™”๋ฅผ ๊นจ๋œจ๋ฆฌ๋Š”์ง€ ์ธ์ง€ํ•œ๋‹ค.

๐Ÿ“– ์šฉ์–ด: SSG(Static Site Generation) โ€” ์•ฑ์„ ๋ฐฐํฌ ์ „(๋นŒ๋“œ ํƒ€์ž„)์— ๋ฏธ๋ฆฌ HTML์„ ์‹น ๋‹ค ์ƒ์„ฑํ•ด๋‘๋Š” ๋ฐฉ์‹.

์ด๊ฒŒ ๋ญ”๊ฐ€? & ์™œ ํ•„์š”ํ•œ๊ฐ€?

์•„๋ฌด๋Ÿฐ ํŠน์ด ์„ค์ • ์—†์ด ์ง  ์ˆœ์ˆ˜ Server Component๋Š” Next.js๊ฐ€ ์ž๋™์œผ๋กœ Static Rendering์œผ๋กœ ๊ฐ„์ฃผํ•ด.
์˜์ฒ  ๋‹˜์ด ์งœ๋˜ /about ํŽ˜์ด์ง€์ฒ˜๋Ÿผ ์ •์ ์ธ ๋ฌธ์„œ๋“ค์„ ํ•œ ๋ฒˆ๋งŒ ๊ตฌ์›Œ์„œ ์ „ ์„ธ๊ณ„ CDN ์— ๋ณต์‚ฌํ•ด๋‘๋ฉด, ์•„๋ฌด๋ฆฌ 10๋งŒ ๋ช…์ด ๋ชฐ๋ ค๋„ ์„œ๋ฒ„ ๋ถ€ํ•˜๊ฐ€ 0(Zero) ์ด๋ž€ ๋œป์ด์ง€.

โŒ ์ˆœ์ง„ํ•œ ์ฝ”๋“œ (Naive Approach)
ํŽ˜์ด์ง€๋ฅผ CSR(React) ๋กœ ๋งŒ๋“ค์–ด ๊ตณ์ด ํด๋ผ์ด์–ธํŠธ์˜ ํ†ต์‹  ๋Šฅ๋ ฅ์„ ๋‚ญ๋น„ํ•˜๊ฒŒ ํ•จ.

โœ… ์šฐ์•„ํ•œ ์ฝ”๋“œ (Pro Approach) - ์™„๋ฒฝํ•œ Static ์ตœ์ ํ™”

// app/about/page.tsx
// ๐Ÿฆ ์˜ํ˜ธ: "์•„๋ฌด๋Ÿฐ ๋™์  ํ•จ์ˆ˜๊ฐ€ ์—†์œผ๋‹ˆ, ์ด ํŽ˜์ด์ง€๋Š” ๋นŒ๋“œ ๋•Œ ๋”ฑ ํ•œ ๋ฒˆ๋งŒ ๊ตฌ์›Œ์ง‘๋‹ˆ๋‹ค."
 
export default function AboutPage() {
  return (
    <main>
      <h1>๋Œ€ํ•œ๋ฏผ๊ตญ No.1 ์Šคํ„ฐ๋”” ๋งค์นญ, ์˜์ˆ˜๋„ค ์ปค๋ฎค๋‹ˆํ‹ฐ</h1>
    </main>
  )
}

๐Ÿงฉ 2. Dynamic Rendering (๊ณผ๊ฑฐ์˜ SSR) ๐ŸŸข

๐ŸŽฏ ์ด ์„น์…˜ ์ดํ›„์— ๋‹น์‹ ์€:

  • ์–ด๋–ค ํ•จ์ˆ˜๊ฐ€ ํŽ˜์ด์ง€๋ฅผ SSR๋กœ '๊ฐ•์ œ ๊ฐ•๋“ฑ'์‹œํ‚ค๋Š”์ง€ ๋ฆฌ์ŠคํŠธ๋ฅผ ๊ธฐ์–ตํ•œ๋‹ค.
  • Dynamic ๋ Œ๋”๋ง์ด ํ•„์š”ํ•œ ํ•„์—ฐ์ ์ธ ์ƒํ™ฉ์„ ๊ตฌ๋ถ„ํ•  ์ˆ˜ ์žˆ๋‹ค.

๐Ÿ“– ์šฉ์–ด: SSR(Server-Side Rendering) โ€” ์‚ฌ์šฉ์ž๊ฐ€ ์ ‘์†ํ•˜๋Š” ๊ทธ ๋Ÿฐํƒ€์ž„ ์‹œ์  ์—, ๊ทธ ์‚ฌ๋žŒ๋งŒ์„ ์œ„ํ•œ ์ตœ์‹  ๋ฐ์ดํ„ฐ์™€ ํ—ค๋”๋กœ HTML์„ ๋ผˆ๋ถ€ํ„ฐ ๊ตฌ์›Œ์ฃผ๋Š” ๋ฐฉ์‹.

์–ธ์ œ ๊ฐ•์ œ ์ „ํ™˜๋˜๋Š”๊ฐ€?

๋‚ด ํŽ˜์ด์ง€๊ฐ€ Static์—์„œ ๋น„์‹ผ Dynamic SSR๋กœ ๊ฐ•๋“ฑ๋˜๋Š” ์กฐ๊ฑด์€ ๋ช…ํ™•ํ•ด. "Next.js๊ฐ€ ๋ฏธ๋ฆฌ ์•Œ ์ˆ˜ ์—†๋Š” ์‹ค์‹œ๊ฐ„ ์œ ์ € ์ •๋ณด"๋ฅผ ๊ฑด๋“œ๋ฆฌ๋Š” ์ˆœ๊ฐ„!

  • cookies() ์ฝ๊ธฐ
  • headers() (์œ ์ €์˜ Agent ๋“ฑ) ์ฝ๊ธฐ
  • searchParams๋ฅผ ํŽ˜์ด์ง€ ํ”„๋กญ์Šค๋กœ ๋ฐ›์•„ ๋ Œ๋”๋ง์— ์“ธ ๋•Œ
// app/dashboard/page.tsx
import { cookies } from 'next/headers'
 
export default async function DashboardPage() {
  // ๐Ÿฃ ์˜์ฒ : "์•„ํ•ญ, ์ฟ ํ‚ค๋ฅผ ์ฝ๋Š” ์ด ๋ผ์ธ์ด ์ถ”๊ฐ€๋˜๋Š” ์ˆœ๊ฐ„,
  // ๋นŒ๋“œ ํƒ€์ž„์—๋Š” ์ด๊ฒŒ ๋ˆ„๊ตฌ ์ฟ ํ‚ค์ธ์ง€ ์•Œ ์ˆ˜๊ฐ€ ์—†์œผ๋‹ˆ ๋Ÿฐํƒ€์ž„ SSR ๋ Œ๋”๋ง์ด ๊ฐ•์ œ๋˜๋Š”๊ตฌ๋‚˜!"
  const cookieStore = cookies()
  const userToken = cookieStore.get('auth_token')
 
  return (
    <main>
      <h1>๋‚ด ์Šคํ„ฐ๋”” ํ˜„ํ™ฉ</h1>
    </main>
  )
}

๐Ÿงฉ 3. ISR: ๋ฐ˜์ž๋™ ๋ Œ๋”๋ง์˜ ๋งˆ๋ฒ• ๐ŸŸก

๐ŸŽฏ ์ด ์„น์…˜ ์ดํ›„์— ๋‹น์‹ ์€:

  • revalidate ์˜ต์…˜์„ ํ†ตํ•ด ์ •์  ํŽ˜์ด์ง€๋ฅผ ์ฃผ๊ธฐ์ ์œผ๋กœ ๊ฐฑ์‹ ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • Stale-While-Revalidate ์ „๋žต์˜ ์žฅ๋‹จ์ ์„ ์ดํ•ดํ•œ๋‹ค.

์˜์ˆ™(๋””์ž์ด๋„ˆ) ๋‹˜์ด ์š”๊ตฌํ–ˆ์–ด. "์˜ํ˜ธ ๋‹˜, ๋ฉ”์ธ ํ™”๋ฉด์˜ '์‹ค์‹œ๊ฐ„ ๊ธ‰์ƒ์Šน ์ธ๊ธฐ ์Šคํ„ฐ๋””' ๋ชฉ๋ก์€ ํ•œ 10๋ถ„์— ํ•œ ๋ฒˆ ์ •๋„๋งŒ ๊ฐฑ์‹ ๋ผ๋„ ์ถฉ๋ถ„ํ•  ๊ฑฐ ๊ฐ™์•„์š”. ์ ‘์†์ž๊ฐ€ ๋ชฐ๋ฆด ๋•Œ ๋กœ๋”ฉ ๊ฑธ๋ฆฌ๋Š” ๊ฑด ์ ˆ๋Œ€ ์‹ซ๊ณ ์š”!"

์˜ํ˜ธ(FE ๋ฆฌ๋“œ) ๋‹˜์€ ์”ฉ ์›ƒ์œผ๋ฉฐ ๋Œ€๋‹ตํ–ˆ์–ด. "ISR๋กœ ์บ์‹œ๋ฅผ ์น˜๋ฉด ์™„๋ฒฝํ•˜์ฃ !"

ISR ๋™์ž‘ ์›๋ฆฌ

์ •์  ํŽ˜์ด์ง€์˜ ๊ฐ•๋ ฅํ•œ ์†๋„๋ฅผ ์œ ์ง€ํ•˜๋ฉด์„œ ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ์ฃผ๊ธฐ์ ์œผ๋กœ ์บ์‹œ๋ฅผ ๊ฐฑ์‹ ํ•ด.

// app/trending/page.tsx
export default async function TrendingPage() {
  // โœ… next: { revalidate: 600 } -> 10๋ถ„(600์ดˆ)์งœ๋ฆฌ ISR ์ „๋žต ์„ ์–ธ!
  const res = await fetch('https://api.youngsu.com/bestsellers', {
    next: { revalidate: 600 }
  })
  const trends = await res.json()
 
  // ๐Ÿฆ ์˜ํ˜ธ: "์‚ฌ์šฉ์ž๋Š” 10๋ถ„ ๋™์•ˆ ๊ตฌ์›Œ์ง„ HTML์„ ๊ด‘์†์œผ๋กœ ๋ฐ›๊ณ , 10๋ถ„์ด ์ง€๋‚˜๋ฉด ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ์ƒˆ ๊ตญ๋ฐฅ์ด ๋“์—ฌ์ง‘๋‹ˆ๋‹ค."
  return <ul>{trends.map(t => <li key={t.id}>{t.title}</li>)}</ul>
}

[์‹œ๋‹ˆ์–ด ๊ด€์ ์˜ ISR์˜ ํ•จ์ • ์ฃผ์˜]
ISR์˜ ๋‹จ์ ์€ ์™„๋ฒฝํ•œ ์‹ค์‹œ๊ฐ„์„ฑ์„ ๋ณด์žฅํ•  ์ˆ˜ ์—†๊ณ , ๋ˆ„๊ตฐ๊ฐ€ ํฌ์ƒ์–‘ 1๋ช…์ด ์ง€๋‚˜๊ฐ„ ์ดํ›„์—์•ผ ์ƒˆ ์ปจํ…์ธ ๋กœ ๋ฎ์–ด์”Œ์›Œ์ง„๋‹ค๋Š” ๊ฑฐ์•ผ(Stale-While-Revalidate ์•„ํ‚คํ…์ฒ˜ ํ•œ๊ณ„). ์ฆ‰๊ฐ ๋ฌดํšจํ™”๊ฐ€ ํ•„์š”ํ•  ๋• ํ›—๋‚  ๋‹ค๋ฃฐ revalidateTag ๋“ฑ ๊ณ ๊ธ‰ ๊ธฐ๋ฒ•์ด ์š”๊ตฌ๋ผ.


๐Ÿงช ๋”ฐ๋ผํ•ด๋ณด๊ธฐ: ๋‚ด ๋ผ์šฐํŠธ๊ฐ€ Static์ธ์ง€ Dynamic์ธ์ง€ ํ™•์ธํ•˜๊ธฐ

๐ŸŽฏ ์ด ์„น์…˜ ์ดํ›„์— ๋‹น์‹ ์€:

  • npm run build ๊ฒฐ๊ณผ๋ฌผ์„ ๋ณด๊ณ  ๋‚ด ์ฝ”๋“œ์˜ ๋ Œ๋”๋ง ์ „๋žต์„ ํŒ๋…ํ•  ์ˆ˜ ์žˆ๋‹ค.

์˜ํ˜ธ ๋‹˜์ด ์˜์ฒ  ๋‹˜์—๊ฒŒ ๊ฐ€์žฅ ๋จผ์ € ๊ฐ€๋ฅด์นœ ๊ฒƒ์€ ๋ฐ”๋กœ ๋นŒ๋“œ ๋กœ๊ทธ ์ฝ๋Š” ๋ฒ•์ด์—ˆ์–ด.

npm run build

๋‹ค ๋๋‚˜๋ฉด ๋Œ€์‹œ๋ณด๋“œ์— ์ด๋Ÿฐ ๋ฉ‹์ง„ ๊ฒฐ๊ณผ๊ฐ€ ๋– .

Route (app)                              Size     First Load JS
โ”Œ โ—‹ /                                    142 B    84.1 kB
โ”œ โ—‹ /about                               182 B    84.2 kB
โ”œ ฦ’ /dashboard                           312 B    84.3 kB
โ”” โ— /trending                            240 B    84.2 kB
 
โ—‹  (Static)  automatically rendered as static HTML (uses no initial props)
ฦ’  (Dynamic) server-rendered on demand using Node.js
โ—  (ISR)     incremental static regeneration (uses revalidate in fetch())
๊ธฐํ˜ธ์ „๋žต์„œ๋ฒ„ ๋ถ€ํ•˜ ์ˆ˜์ค€
โ—‹Static์‚ฌ์‹ค์ƒ ๋น„์šฉ ์ œ๋กœ(0).
ฦ’DynamicํŽ‘์…˜(ฦ’) ๋ชจ์–‘. ์š”์ฒญ ์‹œ๋งˆ๋‹ค ์‹คํ–‰๋˜๋ฏ€๋กœ ํŠธ๋ž˜ํ”ฝ ํŠ€๋ฉด ์กฐ์‹ฌํ•ด์•ผ ํ•จ!
โ—ISR์Šค์œ„ํŠธ ์ŠคํŒŸ. ์ •์  ํŒŒ์ผ ๋ฐฐ๋‹ฌ + ๊ฐ„ํ—์  ๊ฐฑ์‹ 

๐ŸŽฏ ๊ฐœ์ธํ™” ํ”ผ๋“œ์™€ SSR ๊ฒฉ๋ฆฌ ์ „๋žต ๐ŸŸก

๐ŸŽฏ ์ด ์„น์…˜์„ ์ฝ๊ณ  ๋‚˜๋ฉด:

  • ๊ฐœ์ธํ™” ํ”ผ๋“œ๊ฐ€ ์™œ SSR์ด ํ•„์š”ํ•œ์ง€ ์ด์œ ๋ฅผ ์„ค๋ช…ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • Suspense ๊ฒฝ๊ณ„๋กœ SSR ํ•„์š”ํ•œ ๋ถ€๋ถ„๋งŒ ๊ฒฉ๋ฆฌํ•˜๊ณ  ๋‚˜๋จธ์ง€ Static์„ ์œ ์ง€ํ•˜๋Š” ํŒจํ„ด์„ ์ ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
  • useSearchParams ๋ฅผ ์“ธ ๋•Œ ์ „์ฒด ํŽ˜์ด์ง€๊ฐ€ Dynamic์œผ๋กœ ๊ฐ•๋“ฑ๋˜์ง€ ์•Š๋„๋ก ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•ˆ๋‹ค.

๊ฐœ์ธํ™” ํ”ผ๋“œ๋Š” ์™œ SSR์ด์–ด์•ผ ํ• ๊นŒ?

์˜์ˆ˜๋„ค ์ปค๋ฎค๋‹ˆํ‹ฐ ๋ฉ”์ธ ํ”ผ๋“œ ํŽ˜์ด์ง€๋Š” ๋กœ๊ทธ์ธํ•˜๋ฉด "๋‚ด๊ฐ€ ํŒ”๋กœ์šฐํ•˜๋Š” ์Šคํ„ฐ๋”” ๊ทธ๋ฃน" ์˜ ์ตœ์‹  ๊ฒŒ์‹œ๊ธ€๋งŒ ๋ณด์—ฌ์ค˜์•ผ ํ•ด. ์ด ํ”ผ๋“œ๋Š” ์•„๋ž˜ ์ด์œ ๋กœ ๋นŒ๋“œ ํƒ€์ž„์— ๋ฏธ๋ฆฌ ๊ตฌ์›Œ๋‘˜ ์ˆ˜๊ฐ€ ์—†์–ด:

  1. ์‚ฌ์šฉ์ž๋งˆ๋‹ค ๋‹ค๋ฅด๋‹ค โ€” ์˜์ฒ  ๋‹˜์˜ ํ”ผ๋“œ๋Š” "ํ”„๋ก ํŠธ์—”๋“œ" ์Šคํ„ฐ๋””๋งŒ ๋ณด์ด๊ณ , ์˜์ˆ™ ๋‹˜์˜ ํ”ผ๋“œ๋Š” "๋””์ž์ธ" ์Šคํ„ฐ๋””๋งŒ ๋ณด์—ฌ. ๋ฏธ๋ฆฌ ๊ตฌ์šธ ์ˆ˜๊ฐ€ ์—†์ง€.
  2. ์ฟ ํ‚ค/์„ธ์…˜์— ์˜์กดํ•œ๋‹ค โ€” ๋กœ๊ทธ์ธ ์ƒํƒœ๋ฅผ ์„œ๋ฒ„์—์„œ ์ฟ ํ‚ค๋กœ ํ™•์ธํ•ด์•ผ ํ•ด. cookies() ํ•จ์ˆ˜๋ฅผ ์“ฐ๋Š” ์ˆœ๊ฐ„ Static ๋ถˆ๊ฐ€.
  3. ์‹ค์‹œ๊ฐ„์„ฑ์ด ํ•„์š”ํ•˜๋‹ค โ€” ๋ฐฉ๊ธˆ ์˜ฌ๋ผ์˜จ ๊ฒŒ์‹œ๊ธ€์ด ์žˆ์œผ๋ฉด ๋ฐ”๋กœ ๋ณด์—ฌ์•ผ ํ•ด.

์ด ๊ฒฝ์šฐ ํ”ผ๋“œ ์ปดํฌ๋„ŒํŠธ๋งŒํผ์€ SSR(Dynamic Rendering) ์ด ๋งž์•„. ์ ‘์†ํ•  ๋•Œ๋งˆ๋‹ค ์„œ๋ฒ„์—์„œ ์ฟ ํ‚ค๋ฅผ ์ฝ๊ณ , ํ•ด๋‹น ์œ ์ €์˜ ๊ตฌ๋… ์Šคํ„ฐ๋”” ๋ชฉ๋ก์„ DB์—์„œ ๊บผ๋‚ด์„œ HTML์„ ์ฆ‰์„์œผ๋กœ ๋งŒ๋“ค์–ด์•ผ ํ•˜๊ฑฐ๋“ .

๋ฌธ์ œ: ํ”ผ๋“œ ํ•˜๋‚˜ ๋•Œ๋ฌธ์— ํŽ˜์ด์ง€ ์ „์ฒด๊ฐ€ Dynamic์œผ๋กœ ๊ฐ•๋“ฑ๋œ๋‹ค!

์ด ๊ฐœ์ธํ™” ํ”ผ๋“œ๋ฅผ page.tsx ์ตœ์ƒ๋‹จ์— ๋ฐ”๋กœ ๋„ฃ์œผ๋ฉด ํฐ์ผ ๋‚˜.

// โŒ ์ˆœ์ง„ํ•œ ์ฝ”๋“œ: ๋ฉ”์ธ ํŽ˜์ด์ง€ ์ „์ฒด๊ฐ€ Dynamic์œผ๋กœ ๊ฐ•๋“ฑ๋จ
// app/feed/page.tsx
export default async function FeedPage() {
  const cookieStore = await cookies() // ๐Ÿฃ ์˜์ฒ : "์•„๋ฌด ์ƒ๊ฐ ์—†์ด ์—ฌ๊ธฐ์„œ ์ฟ ํ‚ค๋ฅผ ์ฝ์—ˆ๋”๋‹ˆ..."
  const userId = cookieStore.get('user-id')?.value
  const feed = await db.posts.findMany({ where: { authorFollowedBy: userId } })
 
  return (
    <div>
      <HeroSection />        {/* Static์œผ๋กœ ์ถฉ๋ถ„ํ•œ๋ฐ, ๋ฉ๋‹ฌ์•„ Dynamic์œผ๋กœ ๊ฐ•๋“ฑ๋จ */}
      <TrendingTopics />     {/* ISR์ด๋ฉด ์ถฉ๋ถ„ํ•œ๋ฐ, ์—ญ์‹œ Dynamic์œผ๋กœ ๊ฐ•๋“ฑ๋จ */}
      <PersonalizedFeed feed={feed} />  {/* ์ด๊ฒƒ๋งŒ Dynamic์ด ํ•„์š”ํ•œ๋ฐ */}
    </div>
  )
}

๋นŒ๋“œ ๊ฒฐ๊ณผ๋ฅผ ๋ณด๋ฉด /feed ๊ฐ€ ฦ’ (Dynamic) ์œผ๋กœ ํ‘œ์‹œ๋˜์–ด, 1๋งŒ ๋ช…์ด ๋™์‹œ์— ์ ‘์†ํ•˜๋ฉด 1๋งŒ ๋ฒˆ ์ฆ‰์„ ๋ Œ๋”๋ง์ด ๋ฐœ์ƒํ•ด. HeroSection ๊ณผ TrendingTopics ๋Š” Static์œผ๋กœ ์ถฉ๋ถ„ํ–ˆ๋Š”๋ฐ ์–ต์šธํ•˜๊ฒŒ ํฌ์ƒ๋œ ๊ฑฐ์•ผ.

ํ•ด๊ฒฐ์ฑ…: Suspense ๊ฒฝ๊ณ„๋กœ SSR ๋ถ€๋ถ„๋งŒ ์ •๋ฐ€ ๊ฒฉ๋ฆฌ

์˜ํ˜ธ ๋‹˜ ์ด ์ œ์‹œํ•œ ์‹ค์ „ ์•„ํ‚คํ…์ฒ˜์•ผ. SSR์ด ํ•„์š”ํ•œ ์ปดํฌ๋„ŒํŠธ๋งŒ ๋น„๋™๊ธฐ ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋กœ ๋ถ„๋ฆฌํ•˜๊ณ , ๋‚˜๋จธ์ง€๋Š” Static์œผ๋กœ ์œ ์ง€ ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด์•ผ.

// โœ… ์šฐ์•„ํ•œ ์ฝ”๋“œ: SSR ๊ฒฉ๋ฆฌ + Static ๋ณด์กด
// app/feed/page.tsx
import { Suspense } from 'react'
import PersonalizedFeed from '@/components/PersonalizedFeed'
 
// ๐Ÿฆ ์˜ํ˜ธ: "page.tsx ์ž์ฒด๋Š” ์ •์ (Static)์œผ๋กœ ๋‚จ๊ฒจ๋‘๊ณ , ์ฟ ํ‚ค ์‚ฌ์šฉ์ฒ˜๋งŒ ๋„๋ ค๋ƒ…๋‹ˆ๋‹ค."
export default function FeedPage() {
  return (
    <div>
      <HeroSection />
      <TrendingTopics />
 
      <Suspense fallback={<FeedSkeleton />}>
        <PersonalizedFeed />  {/* ์ด ์ปดํฌ๋„ŒํŠธ ์•ˆ์—์„œ๋งŒ cookies() ์‚ฌ์šฉ */}
      </Suspense>
    </div>
  )
}
// app/components/PersonalizedFeed.tsx
// ์ด ์ปดํฌ๋„ŒํŠธ๋งŒ SSR (Dynamic)
import { cookies } from 'next/headers'
 
export default async function PersonalizedFeed() {
  const cookieStore = await cookies()  // โ† ์—ฌ๊ธฐ์„œ๋งŒ ์ฟ ํ‚ค ์ ‘๊ทผ
  const userId = cookieStore.get('user-id')?.value
 
  if (!userId) return <LoginPrompt />
 
  const posts = await db.posts.findMany({
    where: { authorFollowedBy: userId },
    orderBy: { createdAt: 'desc' },
    take: 20,
  })
 
  return <ul>{posts.map(p => <PostCard key={p.id} post={p} />)}</ul>
}

๋นŒ๋“œ ๊ฒฐ๊ณผ ๋น„๊ต:

์ˆœ์ง„ํ•œ ์ฝ”๋“œSuspense ๊ฒฉ๋ฆฌ ์ฝ”๋“œ
/feed ์ „์ฒดฦ’ Dynamic (๋งค๋ฒˆ ์„œ๋ฒ„ ์‹คํ–‰)โ—‹ Static + ์ŠคํŠธ๋ฆฌ๋ฐ
HeroSection๋งค๋ฒˆ ์žฌ๋ Œ๋”CDN์—์„œ ์ฆ‰์‹œ ์‘๋‹ต โœ…
PersonalizedFeedDynamicDynamic (ํ•˜์ง€๋งŒ ๋‚˜๋จธ์ง€๋Š” Static ์œ ์ง€) โœ…

useSearchParams ๋„ ๊ฐ™์€ ์›๋ฆฌ๋กœ ๊ฒฉ๋ฆฌํ•ด์•ผ ํ•ด

ํ€ด์ฆˆ 2๋ฒˆ ํ•ด์„ค์—์„œ ๋‚˜์˜จ searchParams ๋„ ๋งˆ์ฐฌ๊ฐ€์ง€์•ผ. useSearchParams() ๋ฅผ ์“ฐ๋Š” ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ๊ฐ€ page.tsx ์ƒ๋‹จ์— ์žˆ์œผ๋ฉด ์ „์ฒด ํŽ˜์ด์ง€๊ฐ€ Dynamic์œผ๋กœ ๊ฐ•๋“ฑ๋ผ.

// โœ… searchParams ๊ฒฉ๋ฆฌ ํŒจํ„ด
// app/feed/page.tsx โ€” Static ์œ ์ง€
export default function FeedPage() {
  return (
    <div>
      <HeroSection />
      <Suspense fallback={<FilterSkeleton />}>
        <FilteredFeed />  {/* searchParams ์“ฐ๋Š” ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๊ฒฉ๋ฆฌ */}
      </Suspense>
    </div>
  )
}
// app/components/FilteredFeed.tsx
'use client'
import { useSearchParams } from 'next/navigation'
 
export default function FilteredFeed() {
  const searchParams = useSearchParams()
  const category = searchParams.get('category') // ?category=frontend
  // ...
}

โš ๏ธ ์ฃผ์˜: useSearchParams() ๋ฅผ ์“ฐ๋Š” ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ๋ฅผ Suspense๋กœ ๊ฐ์‹ธ์ง€ ์•Š์œผ๋ฉด Next.js๊ฐ€ ๋นŒ๋“œ ๊ฒฝ๊ณ ๋ฅผ ๋‚ด๋ณด๋‚ด. ๋ฐ˜๋“œ์‹œ <Suspense> ๊ฒฝ๊ณ„ ์•ˆ์— ๋„ฃ์–ด์•ผ ํ•ด.

๐Ÿ’ก ํ•œ ์ค„๋กœ ๊ธฐ์–ตํ•˜๊ธฐ
Dynamic์ด ํ•„์š”ํ•œ ๋ถ€๋ถ„๋งŒ <Suspense> ์•ˆ์˜ ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ(์ฟ ํ‚ค ์ ‘๊ทผ)๋‚˜ ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ(searchParams)๋กœ ๊ฒฉ๋ฆฌํ•ด. ๋‚˜๋จธ์ง€๋Š” Static์ด ์œ ์ง€๋ผ์„œ CDN์ด ๋Œ€์‹  ์ฒ˜๋ฆฌํ•ด์ค„ ๊ฑฐ์•ผ.


๐Ÿ ์ด๋ฒˆ์— ๋ฐฐ์šด ๋‚ด์šฉ ์ด์ •๋ฆฌ

  • SSG (โ—‹): ๋ณ€ํ•˜์ง€ ์•Š๋Š” ํ…์ŠคํŠธ์˜ ํšŒ์‚ฌ ์†Œ๊ฐœ๋‚˜ ์—๋Ÿฌ ํผ. ์ตœ์ƒ์˜ ์†๋„.
  • SSR (ฦ’): ์ฟ ํ‚ค ๋“ฑ ๊ฐœ์ธํ™”๊ฐ€ ๋ฌด์กฐ๊ฑด ํ•„์š”ํ•œ ๋Œ€์‹œ๋ณด๋“œ.
  • ISR (โ—): ์ค€-์‹ค์‹œ๊ฐ„์ด ํ•„์š”ํ•œ ์‡ผํ•‘๋ชฐ ๋ฒ ์ŠคํŠธ์…€๋Ÿฌ, ์ปค๋ฎค๋‹ˆํ‹ฐ ์ธ๊ธฐ๊ธ€.

๐Ÿ“ ๋งˆ๋ฌด๋ฆฌ ํ€ด์ฆˆ

Q1. ์ •์  ๋ Œ๋”๋ง๊ณผ ๋™์  ๋ Œ๋”๋ง์„ ๊ฐ€๋ฅด๋Š” ํ•ต์‹ฌ ์งˆ๋ฌธ์€?

โœ… ์ •๋‹ต: ์š”์ฒญ๋งˆ๋‹ค ๋‹ฌ๋ผ์ง€๋Š” ์ž…๋ ฅ์ด ๋ Œ๋”๋ง ๊ฒฐ๊ณผ๋ฅผ ๋ฐ”๊พธ๋Š”๊ฐ€์ด๋‹ค.

๐Ÿ’ก ์ƒ์„ธ ํ•ด์„ค: cookies(), headers(), ์‚ฌ์šฉ์ž๋ณ„ ๊ถŒํ•œ์ฒ˜๋Ÿผ ์š”์ฒญ์— ๋ฌถ์ธ ๊ฐ’์ด ํ•„์š”ํ•˜๋ฉด ๋™์  ๋ Œ๋”๋ง์ด ์ž์—ฐ์Šค๋Ÿฝ๋‹ค. ๋ชจ๋‘์—๊ฒŒ ๊ฐ™์€ ๊ฒฐ๊ณผ๋ผ๋ฉด ์ •์  ๋ Œ๋”๋ง์ด๋‚˜ ISR์„ ๊ฒ€ํ† ํ•  ์ˆ˜ ์žˆ๋‹ค.


Q2. ISR์ด ์–ด์šธ๋ฆฌ๋Š” ๋ฐ์ดํ„ฐ๋Š” ์–ด๋–ค ๋ฐ์ดํ„ฐ์ธ๊ฐ€?

โœ… ์ •๋‹ต: ๋ชจ๋‘์—๊ฒŒ ๊ฐ™์ง€๋งŒ ์ผ์ • ์ฃผ๊ธฐ๋กœ ์ƒˆ๋กœ์›Œ์ ธ์•ผ ํ•˜๋Š” ๋ฐ์ดํ„ฐ๋‹ค.

๐Ÿ’ก ์ƒ์„ธ ํ•ด์„ค: ๊ณต์ง€ ๋ชฉ๋ก์ด๋‚˜ ์ธ๊ธฐ ๊ธ€์ฒ˜๋Ÿผ ๋ช‡ ๋ถ„ ๋Šฆ์–ด๋„ ๊ดœ์ฐฎ์€ ๋ฐ์ดํ„ฐ๋Š” revalidate ์‹œ๊ฐ„์„ ๋‘˜ ์ˆ˜ ์žˆ๋‹ค. ๋‚ด ์•Œ๋ฆผ์ฒ˜๋Ÿผ ์‚ฌ์šฉ์ž๋ณ„ ์ฆ‰์‹œ์„ฑ์ด ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ์—๋Š” ๋งž์ง€ ์•Š๋Š”๋‹ค.


Q3. ์˜์ฒ ์ด์˜ ํ…Œ์ŠคํŠธ ํƒ€์ž„: ํ™ˆ์—๋Š” ๊ณต์ง€ ๋ชฉ๋ก๊ณผ ๋‚ด ์•Œ๋ฆผ ์ˆ˜๊ฐ€ ํ•จ๊ป˜ ์žˆ๋‹ค. ๋ Œ๋”๋ง ์ „๋žต์„ ์–ด๋–ป๊ฒŒ ๋‚˜๋ˆŒ๊นŒ?

โœ… ์ •๋‹ต: ๊ณต์ง€ ๋ชฉ๋ก์€ ์ •์ /ISR ํ›„๋ณด๋กœ, ๋‚ด ์•Œ๋ฆผ ์ˆ˜๋Š” ๋™์  ์˜์—ญ์œผ๋กœ ๋ถ„๋ฆฌํ•œ๋‹ค.

๐Ÿ’ก ์ƒ์„ธ ํ•ด์„ค: ํ•œ ํ™”๋ฉด ์•ˆ์—์„œ๋„ ๋ฐ์ดํ„ฐ ์„ฑ๊ฒฉ์€ ๋‹ค๋ฅผ ์ˆ˜ ์žˆ๋‹ค. ์˜ํ˜ธ๋Š” ํŽ˜์ด์ง€ ์ „์ฒด๋ฅผ ํ•œ ๋‹จ์–ด๋กœ ๋ถ€๋ฅด๊ธฐ ์ „์— ๊ฐ ๋ฐ์ดํ„ฐ์˜ ์‹ ์„ ๋„์™€ ๊ฐœ์ธํ™” ์—ฌ๋ถ€๋ฅผ ๋‚˜๋ˆ„๋ผ๊ณ  ์กฐ์–ธํ•  ๊ฒƒ์ด๋‹ค.

๐Ÿฃ ์˜์ฒ ์ด์˜ ํ‡ด๊ทผ ์ผ๊ธฐ

์˜ค๋Š˜์€ ํŽ˜์ด์ง€๋ฅผ ๋น ๋ฅด๊ฒŒ ๋งŒ๋“ค์ง€ ๋™์ ์œผ๋กœ ๋งŒ๋“ค์ง€ ๊ฐ์œผ๋กœ ๊ณ ๋ฅด์ง€ ์•Š๊ฒŒ ๋๋‹ค.

๐Ÿ’ก "๋ Œ๋”๋ง ์ „๋žต์€ ์„ฑ๋Šฅ ์ทจํ–ฅ์ด ์•„๋‹ˆ๋ผ ๋ฐ์ดํ„ฐ๊ฐ€ ์–ธ์ œ ๋ˆ„๊ตฌ์—๊ฒŒ ๋‹ฌ๋ผ์ง€๋Š”์ง€์˜ ๊ฒฐ๊ณผ๋‹ค."

๋‹ค์Œ ์„ค๊ณ„์—์„œ๋Š” ๋ฐ์ดํ„ฐ๋งˆ๋‹ค ๊ณต๊ฐœ์„ฑ, ์‹ ์„ ๋„, ์š”์ฒญ ์˜์กด์„ฑ์„ ๋จผ์ € ํ‘œ๋กœ ๋‚˜๋ˆ„๊ฒ ๋‹ค.

๐Ÿ”— ๋” ์•Œ์•„๋ณด๊ธฐ