YooBlog

React Server Components

Next.jsยท2023-11-06
post-thumbnail

๐Ÿ”—ย Server Components


React Server Component๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์„œ๋ฒ„์—์„œ ๋ Œ๋”๋งํ•˜๊ณ  ์„ ํƒ์ ์œผ๋กœ ์บ์‹œํ•  ์ˆ˜ ์žˆ๋Š” UI๋ฅผ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Next.js์—์„œ๋Š”, route segments๋กœ ๋ Œ๋”๋ง ๊ณผ์ •์„ ๋” ์กฐ๊ฐ๋‚ด๊ณ  ์ด๊ฒƒ์„ ์‹ค์‹œ๊ฐ„์œผ๋กœ ์ „์†ก(streaming)ํ•˜์—ฌ ๋ถ€๋ถ„์ ์œผ๋กœ ๋ Œ๋”๋งํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
ย 
ย 

๐Ÿ”—ย Benefits of Server Rendering


์„œ๋ฒ„์—์„œ ๋ Œ๋”๋งํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ด์ ๋“ค์ด ์žˆ์Šต๋‹ˆ๋‹ค:
ย 
Data Fetching
Server Components๋Š” ์„œ๋ฒ„์—์„œ ๋ฐ์ดํ„ฐ ํŒจ์นญ์„ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค. ๋ฐ์ดํ„ฐ ์†Œ์Šค(database, ์™ธ๋ถ€ API, cache, file systemโ€ฆ)์— ๋” ๊ฐ€๊นŒ์šด ์„œ๋ฒ„์—์„œ ๋ Œ๋”๋งํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ Œ๋”๋ง์— ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ๋ฐ ๊ฑธ๋ฆฌ๋Š” ์‹œ๊ฐ„์„ ์ค„์—ฌ์ฃผ๊ณ , ํด๋ผ์ด์–ธํŠธ๊ฐ€ ํ•ด์•ผ ํ•˜๋Š” ์š”์ฒญ์˜ ์–‘์„ ์ค„์—ฌ์ฃผ์–ด ์„ฑ๋Šฅ์„ ํ–ฅ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
Security
ํ† ํฐ ๋ฐ API ํ‚ค์™€ ๊ฐ™์€ ๋ฏผ๊ฐํ•œ ๋ฐ์ดํ„ฐ ๋ฐ ๋กœ์ง์„ ํด๋ผ์ด์–ธํŠธ์— ๋…ธ์ถœ์‹œํ‚ค์ง€ ์•Š๊ณ  ์„œ๋ฒ„์— ์•ˆ์ „ํ•˜๊ฒŒ ๋ณด๊ด€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
Caching
์„œ๋ฒ„์—์„œ ๋ Œ๋”๋งํ•˜๋ฉด ๊ฒฐ๊ณผ๋ฌผ์„ ์บ์‹œํ•  ์ˆ˜ ์žˆ๊ณ  ์ดํ›„์˜ ์š”์ฒญ ๋ฐ ์—ฌ๋Ÿฌ ์‚ฌ์šฉ์ž์—๊ฒŒ ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ๊ฐ ์š”์ฒญ๋งˆ๋‹ค ์ˆ˜ํ–‰๋˜๋Š” ๋ Œ๋”๋ง๊ณผ ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ ์–‘์„ ์ค„์—ฌ ์„ฑ๋Šฅ์„ ํ–ฅ์ƒ์‹œํ‚ค๊ณ  ๋น„์šฉ์„ ์ ˆ๊ฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
Bundle Sizes
์ด์ „์—๋Š” ํด๋ผ์ด์–ธํŠธ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋ฒˆ๋“ค ํฌ๊ธฐ์— ์˜ํ–ฅ์„ ๋ผ์น  ์ˆ˜ ์žˆ์—ˆ๋˜ ํฐ ๋””ํŽœ๋˜์‹œ๋“ค์„ ์„œ๋ฒ„์—์„œ ๊ฐ€์ง€๊ณ  ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ๋Š๋ฆฐ ์ธํ„ฐ๋„ท ์—ฐ๊ฒฐ์ด๋‚˜ ์„ฑ๋Šฅ์ด ๋‚ฎ์€ ๊ธฐ๊ธฐ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์‚ฌ์šฉ์ž๋“ค์—๊ฒŒ ์ด์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์™œ๋ƒํ•˜๋ฉด ํด๋ผ์ด์–ธํŠธ๋Š” ๋””ํŽœ๋˜์‹œ๋ฅผ ์œ„ํ•ด ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ๋‹ค์šด๋กœ๋“œํ•˜๊ณ  ํ•ด์„ํ•˜๊ณ  ์‹คํ–‰ํ•  ํ•„์š”๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.
Initial Page Load and First Contentful Paint (FCP)
ํด๋ผ์ด์–ธํŠธ์—์„œ ํŽ˜์ด์ง€์— ํ•„์š”ํ•œ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ๋‹ค์šด๋กœ๋“œ, ํ•ด์„, ์‹คํ–‰ํ•˜๋Š” ๊ฒƒ์„ ๊ธฐ๋‹ค๋ฆด ํ•„์š” ์—†์ด, ์„œ๋ฒ„์—์„œ HTML์„ ์ƒ์„ฑํ•ด์„œ ์œ ์ €๋“ค์ด ์ฆ‰์‹œ ํŽ˜์ด์ง€๋ฅผ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
Search Engine Optimization and Social Network Shareability
๋ Œ๋”๋ง๋œ HTML์€ ๊ฒ€์ƒ‰ ์—”์ง„ ๋ด‡์ด ์ƒ‰์ธํ™”(index)ํ•˜๋Š”๋ฐ ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ์œผ๋ฉฐ ์†Œ์…œ ๋„คํŠธ์›Œํฌ ๋ด‡์ด ํŽ˜์ด์ง€์˜ ์†Œ์…œ ์นด๋“œ ๋ฏธ๋ฆฌ๋ณด๊ธฐ๋ฅผ ๋งŒ๋“œ๋Š”๋ฐ์—๋„ ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
Streaming
Server Components๋Š” ๋ Œ๋”๋ง ์ž‘์—…์„ ์กฐ๊ฐ์œผ๋กœ ๋‚˜๋ˆ„์–ด, ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์ค€๋น„๋  ๋•Œ๋งˆ๋‹ค ์‹ค์‹œ๊ฐ„์œผ๋กœ ์ „์†กํ•ด์ค๋‹ˆ๋‹ค. ์ด๋Š” ์œ ์ €๊ฐ€ ์ „์ฒด ํŽ˜์ด์ง€๊ฐ€ ๋ Œ๋”๋ง๋˜๋Š” ๊ฒƒ์„ ๊ธฐ๋‹ค๋ฆด ํ•„์š” ์—†์ด, ํŽ˜์ด์ง€์˜ ์ผ๋ถ€๋ฅผ ๋” ๋นจ๋ฆฌ ๋ณผ ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค.
ย 
ย 

๐Ÿ”—ย How are Server Components rendered?


์„œ๋ฒ„์—์„œ, Next.js๋Š” React์˜ API๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ Œ๋”๋ง์„ ์กฐ์œจํ•ฉ๋‹ˆ๋‹ค. ๋ Œ๋”๋ง ์ž‘์—…์€ ๊ฐœ๋ณ„ ๊ฒฝ๋กœ ์„ธ๊ทธ๋จผํŠธ์™€ Suspense Boundaries์— ๋”ฐ๋ผ ์กฐ๊ฐ์œผ๋กœ ๋‚˜๋‰ฉ๋‹ˆ๋‹ค.
ย 
๊ฐ ์กฐ๊ฐ์€ ๋‘ ๋‹จ๊ณ„๋กœ ๋ Œ๋”๋ง ๋ฉ๋‹ˆ๋‹ค:
  1. React๋Š” ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋ฅผ React Server Componet Payload(RSC Payload)๋ผ๊ณ  ๋ถˆ๋ฆฌ๋Š” ํŠน๋ณ„ํ•œ ๋ฐ์ดํ„ฐ ํ˜•์‹์œผ๋กœ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค.
  1. Next.js๋Š” HTML์„ ์„œ๋ฒ„์—์„œ ๋ Œ๋”๋งํ•˜๊ธฐ ์œ„ํ•ด RSC Payload์™€ Client Component JavaScript instructions๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
ย 
๊ทธ ํ›„, ํด๋ผ์ด์–ธํŠธ์—์„œ:
  1. ๋ Œ๋”๋ง ๋œ HTML๋กœ ๋น ๋ฅด๊ณ  ์ƒํ˜ธ ์ž‘์šฉ์ด ์—†๋Š” ๋ฏธ๋ฆฌ๋ณด๊ธฐ๋ฅผ ์ฆ‰์‹œ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. - ์ดˆ๊ธฐ ํŽ˜์ด์ง€ ๋กœ๋“œ ์‹œ
  1. RSC Payload๋Š” ํด๋ผ์ด์–ธํŠธ์™€ ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ ํŠธ๋ฆฌ๋ฅผ ์กฐํ™”์‹œํ‚ค๊ณ  DOM์„ ์—…๋ฐ์ดํŠธํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
  1. JavaScript instructions๋Š” ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ๋ฅผ ํ•˜์ด๋“œ๋ ˆ์ด์…˜ํ•˜๊ณ  ์•ฑ์„ ์ƒํ˜ธ ์ž‘์šฉ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.
ย 
๐Ÿ—’๏ธ
What is the RSC Payload?
RSC Payload๋Š” ๋ Œ๋”๋ง๋œ ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ ํŠธ๋ฆฌ์˜ ๊ฐ„๋žตํ•œ ์ด์ง„ ํ‘œํ˜„ ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค. ํด๋ผ์ด์–ธํŠธ์—์„œ ๋ฆฌ์•กํŠธ์— ์˜ํ•ด ๋ธŒ๋ผ์šฐ์ € DOM์„ ์—…๋ฐ์ดํŠธํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
The RSC Payload contains:
  • ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ์˜ ๋ Œ๋”๋ง๋œ ๊ฒฐ๊ณผ๋ฌผ
  • ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ Œ๋”๋ง๋˜์–ด์•ผ ํ•  ์ž๋ฆฌ๋ฅผ ํ‘œ์‹œํ•˜๋Š” Placeholders์™€ ๊ทธ ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ์˜ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ํŒŒ์ผ์— ๋Œ€ํ•œ ์ฐธ์กฐ
  • ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ์—์„œ ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ๋กœ ์ „๋‹ฌ๋˜๋Š” ๋ชจ๋“  props
ย 
ย 

๐Ÿ”—ย Server Rendering Strategies


์„ธ๊ฐ€์ง€ ์„œ๋ฒ„ ๋ Œ๋”๋ง ์ „๋žต์ด ์žˆ์Šต๋‹ˆ๋‹ค.
ย 

1. Static Rendering (Default)

Static Rendering์„ ์‚ฌ์šฉํ•˜๋ฉด, ๋ผ์šฐํŠธ๊ฐ€ ๋นŒ๋“œ ์‹œ๊ฐ„ ๋˜๋Š” ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ revalidation ํ›„ ๋ Œ๋”๋ง๋ฉ๋‹ˆ๋‹ค. ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ์บ์‹œํ•˜๊ณ  Content Delivery Network (CDN)์— ์ €์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ์ตœ์ ํ™”๋Š” ๋ Œ๋”๋ง ์ž‘์—…์˜ ๊ฒฐ๊ณผ๋ฅผ ์‚ฌ์šฉ์ž์™€ ์„œ๋ฒ„ ์š”์ฒญ ๊ฐ„์— ๊ณต์œ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค.
๊ฐœ์ธํ™” ๋˜์ง€์•Š๋Š” ์ •๋ณด๋‚˜ ๋นŒ๋“œ ์‹œ์ ์— ์•Œ ์ˆ˜ ์žˆ๋Š” ๋ฐ์ดํ„ฐ์˜ ๊ฒฝ์šฐ ์ ํ•ฉํ•ฉ๋‹ˆ๋‹ค. ex. ๋ธ”๋กœ๊ทธ ํฌ์ŠคํŠธ, ์ œํ’ˆ ์ƒ์„ธํŽ˜์ด์ง€
ย 

2. Dynamic Rendering

Dynamic Rendering์„ ์‚ฌ์šฉํ•˜๋ฉด, ์‚ฌ์šฉ์ž๊ฐ€ ์š”์ฒญํ•˜๋ฉด ๋ผ์šฐํŠธ๋ฅผ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค.
๊ฐœ์ธํ™”๋œ ์ •๋ณด๋‚˜ ์š”์ฒญ ์‹œ์— ์•Œ ์ˆ˜ ์žˆ๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ ์ ํ•ฉํ•ฉ๋‹ˆ๋‹ค. ex. cookies, URLโ€™s search params
ย 
Switching to Dynamic Rendering
๋ Œ๋”๋งํ•˜๋Š” ๋™์•ˆ dynamic function ๋˜๋Š” uncached data request์ด ๋ฐœ๊ฒฌ๋˜๋ฉด Next.js๋Š” ์ „์ฒด ๊ฒฝ๋กœ(route)๋ฅผ ๋™์ ์œผ๋กœ ๋ Œ๋”๋งํ•˜๋„๋ก ์ „ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ๋‘˜ ์ค‘ ํ•˜๋‚˜๋ผ๋„ ๋ฐœ๊ฒฌ๋˜๋ฉด ์ „์ฒด ๊ฒฝ๋กœ๋ฅผ ๋™์  ๋ Œ๋”๋งํ•˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.
Dynamic Function Example
cookies()
headers()
useSearchParams()
searchParams
ย 
Next.js๊ฐ€ ์ฝ”๋“œ์—์„œ ์‚ฌ์šฉํ•œ features, APIs๋ฅผ ๋ณด๊ณ  ๊ฐ ๊ฒฝ๋กœ์— ๋Œ€ํ•ด ๊ฐ€์žฅ ์ ํ•ฉํ•œ ๋ Œ๋”๋ง ์ „๋žต์„ ์ž๋™์œผ๋กœ ์„ ํƒํ•ด์ฃผ๊ธฐ ๋•Œ๋ฌธ์— ๊ฐœ๋ฐœ์ž๋Š” static์ธ์ง€ dynamic์ธ์ง€ ์„ ํƒํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ๋Œ€์‹ ์—, ํŠน์ • ๋ฐ์ดํ„ฐ๋ฅผ ์–ธ์ œ ์บ์‹œํ•˜๊ณ  ์žฌ๊ฒ€์ฆํ• ์ง€, ๊ทธ๋ฆฌ๊ณ  ์–ด๋–ค UI์„ ๋ถ€๋ถ„์ ์œผ๋กœ ์ŠคํŠธ๋ฆฌ๋ฐํ•  ์ง€์— ์ง‘์ค‘ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.
ย 

3. Streaming

notion image
์ŠคํŠธ๋ฆฌ๋ฐ์€ UI๋ฅผ ์ ์ง„์ ์œผ๋กœ ๊ทธ๋ฆด ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค. ์ž‘์—…์€ ์กฐ๊ฐ์œผ๋กœ ๋ถ„๋ฆฌ๋˜๊ณ  ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์ค€๋น„๋˜๋ฉด ์‹ค์‹œ๊ฐ„์œผ๋กœ ์กฐ๊ฐ์„ ๋ณด๋‚ด์ค๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์œ ์ €๊ฐ€ ํŽ˜์ด์ง€์˜ ์ „์ฒด ๋‚ด์šฉ์ด ์ „๋ถ€ ๋ Œ๋”๋ง๋Š” ๊ฒƒ์„ ๊ธฐ๋‹ค๋ฆด ํ•„์š”์—†์ด, ํŽ˜์ด์ง€์˜ ๋ถ€๋ถ„์„ ์ฆ‰๊ฐ์ ์œผ๋กœ ๋ณผ ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค.
notion image
์ŠคํŠธ๋ฆฌ๋ฐ์€ App Router์— ๊ธฐ๋ณธ ๋‚ด์žฅ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์ดˆ๊ธฐ ํŽ˜์ด์ง€ ๋กœ๋”ฉ ์„ฑ๋Šฅ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์ „์ฒด ๊ฒฝ๋กœ์˜ ๋ Œ๋”๋ง์„ ์ฐจ๋‹จํ•  ์ˆ˜ ์žˆ๋Š” ๋Š๋ฆฐ ๋ฐ์ดํ„ฐ์— ์˜์กดํ•˜๋Š” UI์˜ ์„ฑ๋Šฅ์„ ๊ฐœ์„ ํ•˜๋Š” ๋ฐ์—๋„ ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ๋“ค์–ด ์ œํ’ˆ ํŽ˜์ด์ง€์˜ ๋ฆฌ๋ทฐ๋“ค..
loading.js, React Suspense๋ฅผ ์‚ฌ์šฉํ•ด ์ŠคํŠธ๋ฆฌ๋ฐ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
ย 

์œ ํ˜„์ง€

์•ˆ๋…•ํ•˜์„ธ์š”

์‹œ๋ฆฌ์ฆˆNext.js

ํ™ˆ์œผ๋กœ