# [[React Suspense]] ## ๐Ÿ“Œ Brief Summary [[React Suspense]]๋Š” `React.lazy()`์™€ ํ•จ๊ป˜ ์‚ฌ์šฉ๋˜์–ด ๋™์ ์œผ๋กœ ๊ฐ€์ ธ์˜ค๋Š” ์ปดํฌ๋„ŒํŠธ(์ง€์—ฐ ๋กœ๋”ฉ)์˜ ๋กœ๋”ฉ ์ƒํƒœ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” React์˜ ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค [1-3]. ๋ชจ๋“ˆ์ด๋‚˜ ๋ฐ์ดํ„ฐ๊ฐ€ ๋กœ๋“œ๋˜๋Š” ๋™์•ˆ ์‚ฌ์šฉ์ž์—๊ฒŒ ๋ณด์—ฌ์ค„ ๋Œ€์ฒด UI(Fallback UI, ์˜ˆ: ๋กœ๋”ฉ ์Šคํ”ผ๋„ˆ๋‚˜ ์Šค์ผˆ๋ ˆํ†ค ํ™”๋ฉด)๋ฅผ ์ •์˜ํ•˜๋Š” ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค [2]. ์ด๋ฅผ ํ†ตํ•ด ์ดˆ๊ธฐ ๋ฒˆ๋“ค ํฌ๊ธฐ๋ฅผ ์ค„์ด๊ณ  ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๋กœ๋”ฉ ์†๋„์™€ ์ธ์ง€๋˜๋Š” ์„ฑ๋Šฅ(Perceived Performance)์„ ํฌ๊ฒŒ ํ–ฅ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค [2, 4]. ## ๐Ÿ“– Core Content * **์ง€์—ฐ ๋กœ๋”ฉ(Lazy Loading)๊ณผ์˜ ๊ฒฐํ•ฉ**: ๋Œ€์šฉ๋Ÿ‰ JavaScript ๋ฒˆ๋“ค์„ ๋ถ„ํ• ํ•˜๊ธฐ ์œ„ํ•ด `React.lazy()`๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ปดํฌ๋„ŒํŠธ๋ฅผ ํ•„์š”ํ•œ ์‹œ์ ์— ๋น„๋™๊ธฐ์ ์œผ๋กœ ๋ถˆ๋Ÿฌ์˜ฌ ๋•Œ, ๊ทธ ๋ถˆ๋Ÿฌ์˜ค๋Š” ์‹œ๊ฐ„ ๋™์•ˆ ๋ Œ๋”๋ง๋  UI๋ฅผ `` ์ปดํฌ๋„ŒํŠธ์˜ `fallback` ์†์„ฑ์œผ๋กœ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค [1, 2]. * *๊ตฌํ˜„ ์˜ˆ์‹œ:* `const Dashboard = React.lazy(() => import('./Dashboard'));` ํ›„ `}> ` ํ˜•ํƒœ๋กœ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค [1, 2]. * **๋ผ์šฐํŠธ ๋ฐ ๋ฌด๊ฑฐ์šด ๊ธฐ๋Šฅ ๋ถ„ํ• **: ๋ผ์šฐํŠธ ์ˆ˜์ค€์˜ ์ปดํฌ๋„ŒํŠธ๋‚˜ ๋ฌด๊ฑฐ์šด UI ๋ธ”๋ก(์˜ˆ: ๋Œ€์‹œ๋ณด๋“œ, ์ฐจํŠธ, PDF ๋ทฐ์–ด ๋“ฑ)์„ ๋™์  ์ž„ํฌํŠธ(Dynamic Import)๋กœ ์ „ํ™˜ํ•œ ๋’ค, ๊ฐ ๋ผ์šฐํŠธ ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ``๋กœ ๊ฐ์‹ธ๋ฉด ๊ฐ ํŽ˜์ด์ง€๊ฐ€ ๋…๋ฆฝ์ ์ธ ์ฒญํฌ(Chunk)๊ฐ€ ๋˜์–ด ์‚ฌ์šฉ์ž๊ฐ€ ํ•ด๋‹น ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•  ๋•Œ๋งŒ ์ฝ”๋“œ๊ฐ€ ๋‹ค์šด๋กœ๋“œ๋ฉ๋‹ˆ๋‹ค [3, 5, 6]. * **๋™์‹œ์„ฑ ๊ธฐ๋Šฅ(Concurrent Features)๊ณผ์˜ ํ†ตํ•ฉ**: React 18 ์ดํ›„์˜ ๋™์‹œ์„ฑ ํ›…์ธ `useTransition` ๋“ฑ๊ณผ ๊ฒฐํ•ฉํ•˜์—ฌ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ๋ฌด๊ฑฐ์šด ๋ฐ์ดํ„ฐ ํ•„ํ„ฐ๋ง ๋“ฑ์˜ ์ž‘์—…์ด ์ง„ํ–‰๋˜๋Š” ๋™์•ˆ ์ฆ‰๊ฐ์ ์ธ ์‚ฌ์šฉ์ž ์ƒํ˜ธ์ž‘์šฉ(์ž…๋ ฅ ๋“ฑ)์„ ์ฐจ๋‹จํ•˜์ง€ ์•Š๊ณ  ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์ž‘์—…์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๋ฉฐ, ํ•„์š”์— ๋”ฐ๋ผ Suspense์˜ Fallback UI๋ฅผ ํ‘œ์‹œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค [7, 8]. ## โš–๏ธ Trade-offs & Caveats * **์ ์šฉ ์œ„์น˜์˜ ์ œํ•œ (Above-the-fold ์ฃผ์˜)**: ๋ชจ๋“  ์ปดํฌ๋„ŒํŠธ์— ์ง€์—ฐ ๋กœ๋”ฉ๊ณผ Suspense๋ฅผ ๋ฌด๋ถ„๋ณ„ํ•˜๊ฒŒ ์ ์šฉํ•ด์„œ๋Š” ์•ˆ ๋ฉ๋‹ˆ๋‹ค. ํŽ˜์ด์ง€ ์ดˆ๊ธฐ ๋กœ๋“œ ์‹œ ์ฆ‰์‹œ ๋ณด์—ฌ์•ผ ํ•˜๋Š” ํ•ต์‹ฌ ์ฝ˜ํ…์ธ (Above-the-fold)๋‚˜ ๋ Œ๋”๋ง ์†๋„๊ฐ€ ๋นจ๋ผ ์ฆ‰๊ฐ์ ์œผ๋กœ ํ‘œ์‹œ๋˜์–ด์•ผ ํ•˜๋Š” ์š”์†Œ์—๋Š” Suspense๋ฅผ ํ†ตํ•œ ์ง€์—ฐ ๋กœ๋”ฉ ์ ์šฉ์„ ํ”ผํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค [5]. * **๊ธฐํƒ€ ์ œ์•ฝ ์‚ฌํ•ญ**: ์†Œ์Šค์— ๊ด€๋ จ ์ •๋ณด๊ฐ€ ๋ถ€์กฑํ•ฉ๋‹ˆ๋‹ค. (์ œ๊ณต๋œ ์†Œ์Šค ๋ฐ์ดํ„ฐ ๋‚ด์—์„œ๋Š” Suspense ์ž์ฒด์˜ ๊นŠ์€ ๊ธฐ์ˆ ์  ํ•œ๊ณ„๋‚˜ ์„œ๋ฒ„ ์‚ฌ์ด๋“œ ๋ Œ๋”๋ง ์‹œ์˜ ๋ณต์žกํ•œ ๋ถ€์ž‘์šฉ ๋“ฑ์— ๋Œ€ํ•œ ๊ตฌ์ฒด์ ์ธ ์–ธ๊ธ‰์€ ์—†์œผ๋ฉฐ, ์ฃผ๋กœ ๋ฒˆ๋“ค ์ตœ์ ํ™”๋ฅผ ์œ„ํ•œ ๊ธ์ •์ ์ธ ํ™œ์šฉ๋ฒ• ์œ„์ฃผ๋กœ ์„ค๋ช…๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.) ## ๐Ÿ”— Knowledge Connections ### Related Concepts #### [๊ด€๊ณ„ ์œ ํ˜• A (์•„ํ‚คํ…์ฒ˜/๊ธฐ๋ฐ˜ ๊ธฐ์ˆ )] * [[Code Splitting]] * ์—ฐ๊ฒฐ ์ด์œ : ๊ฑฐ๋Œ€ํ•œ JavaScript ๋ฒˆ๋“ค์„ ์ž‘์€ ๋‹จ์œ„์˜ ์ฒญํฌ(Chunk)๋กœ ์ชผ๊ฐœ๋Š” ์•„ํ‚คํ…์ฒ˜ ๊ธฐ๋ฒ•์œผ๋กœ, Suspense๋ฅผ ๋„์ž…ํ•˜๋Š” ํ•ต์‹ฌ ๋ชฉ์ ์ž…๋‹ˆ๋‹ค [4, 9]. * ์ด ๊ฐœ๋…์„ ํ†ตํ•ด ๋” ๊นŠ๊ฒŒ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๋Š” ๋ถ€๋ถ„: ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ๋ถˆํ•„์š”ํ•œ ์ฝ”๋“œ๋ฅผ ๋‹ค์šด๋กœ๋“œํ•˜์ง€ ์•Š๊ฒŒ ํ•˜์—ฌ FCP(First Contentful Paint) ๋“ฑ์˜ ์„ฑ๋Šฅ ์ง€ํ‘œ๋ฅผ ๊ฐœ์„ ํ•˜๋Š” ์›๋ฆฌ. * [[Concurrent Rendering]] * ์—ฐ๊ฒฐ ์ด์œ : Suspense๋Š” ๋™์‹œ์„ฑ ๋ Œ๋”๋ง ๊ธฐ๋Šฅ(`useTransition`, `useDeferredValue`)๊ณผ ํ•จ๊ป˜ ์‚ฌ์šฉ๋˜์–ด ๋ Œ๋”๋ง ์ž‘์—…์˜ ์šฐ์„ ์ˆœ์œ„๋ฅผ ์กฐ์ •ํ•˜๊ณ  UI ์ฐจ๋‹จ(Jank)์„ ๋ฐฉ์ง€ํ•˜๋Š” ๋ฐ ํ™œ์šฉ๋ฉ๋‹ˆ๋‹ค [8, 10]. * ์ด ๊ฐœ๋…์„ ํ†ตํ•ด ๋” ๊นŠ๊ฒŒ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๋Š” ๋ถ€๋ถ„: React๊ฐ€ ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ๋ Œ๋”๋ง ์ž‘์—…์„ ์ผ์‹œ ์ค‘์ง€, ์ค‘๋‹จ, ์žฌ๊ฐœํ•˜๋Š” ๋ฉ”์ปค๋‹ˆ์ฆ˜. #### [๊ด€๊ณ„ ์œ ํ˜• B (๊ตฌํ˜„/ํ™œ์šฉ ๋„๊ตฌ)] * [[React.lazy()]] * ์—ฐ๊ฒฐ ์ด์œ : ์ปดํฌ๋„ŒํŠธ์˜ ๋™์  ์ž„ํฌํŠธ(Dynamic Import)๋ฅผ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ด์ฃผ๋Š” ํ•จ์ˆ˜๋กœ, ํ•ญ์ƒ ``์™€ ์ง์„ ์ด๋ฃจ์–ด ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค [1-3]. * ์ด ๊ฐœ๋…์„ ํ†ตํ•ด ๋” ๊นŠ๊ฒŒ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๋Š” ๋ถ€๋ถ„: ๋Ÿฐํƒ€์ž„์— ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์ฝ”๋“œ๋ฅผ ์˜จ๋””๋งจ๋“œ(On-demand) ๋ฐฉ์‹์œผ๋กœ ์š”์ฒญํ•˜์—ฌ ๋ Œ๋”๋ง ํŠธ๋ฆฌ์— ์ฃผ์ž…ํ•˜๋Š” ๋ฐฉ๋ฒ•. ### Deeper Research Questions * React Suspense๋ฅผ ํ™œ์šฉํ•œ ๋ฐ์ดํ„ฐ ํŒจ์นญ(Data Fetching) ๋กœ๋”ฉ ์ฒ˜๋ฆฌ๋Š” ๊ธฐ์กด `useEffect` ๊ธฐ๋ฐ˜์˜ ๋กœ๋”ฉ ์ƒํƒœ(isLoading) ๊ด€๋ฆฌ์™€ ๋น„๊ตํ•˜์—ฌ ๋ Œ๋”๋ง ์„ฑ๋Šฅ ๋ฐ ์ฝ”๋“œ ๋ณต์žก๋„ ๋ฉด์—์„œ ์–ด๋–ค ์ฐจ์ด๋ฅผ ๋งŒ๋“ค์–ด๋‚ด๋Š”๊ฐ€? * Next.js์˜ ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ(Server Components) ์•„ํ‚คํ…์ฒ˜ ํ™˜๊ฒฝ์—์„œ Suspense ๊ฒฝ๊ณ„(Boundaries)๋Š” ์ŠคํŠธ๋ฆฌ๋ฐ(Streaming) ๋ Œ๋”๋ง๊ณผ ์–ด๋–ป๊ฒŒ ์ƒํ˜ธ์ž‘์šฉํ•˜๋Š”๊ฐ€? * ๋‹ค์ˆ˜์˜ `` ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ถ€๋ชจ-์ž์‹ ๊ด€๊ณ„๋กœ ์ค‘์ฒฉ๋˜์–ด ์žˆ์„ ๋•Œ, Fallback UI๊ฐ€ ํ™”๋ฉด์— ๋‚˜ํƒ€๋‚˜๋Š” ์šฐ์„ ์ˆœ์œ„์™€ ๋ Œ๋”๋ง ๋™์ž‘ ๋ฐฉ์‹์€ ์–ด๋–ป๊ฒŒ ๊ฒฐ์ •๋˜๋Š”๊ฐ€? * Above-the-fold ์ฝ˜ํ…์ธ ์— Suspense๋ฅผ ์ž˜๋ชป ์ ์šฉํ–ˆ์„ ๋•Œ ๋ฐœ์ƒํ•˜๋Š” LCP(Largest Contentful Paint) ์„ฑ๋Šฅ ์ €ํ•˜์˜ ๊ตฌ์ฒด์ ์ธ ๋ธŒ๋ผ์šฐ์ € ๋ Œ๋”๋ง ๋ฉ”์ปค๋‹ˆ์ฆ˜์€ ๋ฌด์—‡์ธ๊ฐ€? * ์—๋Ÿฌ ๊ฒฝ๊ณ„([[Error Boundaries]]) ์ปดํฌ๋„ŒํŠธ์™€ Suspense๋ฅผ ๊ฒฐํ•ฉํ•˜์—ฌ ์ง€์—ฐ ๋กœ๋”ฉ(Lazy Loading) ์ค‘ ๋„คํŠธ์›Œํฌ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๋•Œ ์ด๋ฅผ ์–ด๋–ป๊ฒŒ ์šฐ์•„ํ•˜๊ฒŒ ๋ณต๊ตฌ(Graceful Degradation)ํ•  ์ˆ˜ ์žˆ๋Š”๊ฐ€? ### Practical Application Contexts * **Implementation:** `React.lazy()`๋ฅผ ์ด์šฉํ•ด ๋ผ์šฐํŠธ๋‚˜ ๋ฌด๊ฑฐ์šด ์ฐจํŠธ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ถ„๋ฆฌํ•˜๊ณ , ์ด๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ ๋‹จ์— `}>`๋ฅผ ๊ฐ์‹ธ์–ด ๋ชจ๋“ˆ ๋‹ค์šด๋กœ๋“œ ๋Œ€๊ธฐ ์‹œ๊ฐ„์„ ์‹œ๊ฐ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค [2, 3]. * **System Design:** Vite๋‚˜ Webpack ๊ฐ™์€ ๋ชจ๋˜ ๋ฒˆ๋“ค๋Ÿฌ ํ™˜๊ฒฝ์—์„œ ๋™์  ์ž„ํฌํŠธ๋ฅผ ์„ค๊ณ„ํ•  ๋•Œ, ๋ผ์šฐํŠธ ๋‹จ์œ„๋ณ„ ์ฝ”๋“œ ์Šคํ”Œ๋ฆฌํŒ…์„ ์•„ํ‚คํ…์ฒ˜์˜ ๊ธฐ๋ณธ ํ‘œ์ค€์œผ๋กœ ์‚ผ์•„ ๋ฉ”์ธ ๋ฒˆ๋“ค ์‚ฌ์ด์ฆˆ๋ฅผ ์ค„์ž…๋‹ˆ๋‹ค [3, 9, 11]. * **Operation / Maintenance:** ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์šด์˜ ์ค‘ ์›นํŒฉ ๋ฒˆ๋“ค ์•„๋‚ ๋ผ์ด์ €(Webpack Bundle Analyzer)๋‚˜ ๋ธŒ๋ผ์šฐ์ €์˜ Network ํƒญ์„ ํ†ตํ•ด Suspense ์ ์šฉ ์ดํ›„ JS ์ฒญํฌ ๋ถ„ํ• ์ด ์ œ๋Œ€๋กœ ์ด๋ฃจ์–ด์กŒ๋Š”์ง€ ์ง€์†์ ์œผ๋กœ ํ”„๋กœํŒŒ์ผ๋ง ๋ฐ ๋ชจ๋‹ˆํ„ฐ๋งํ•ฉ๋‹ˆ๋‹ค [12]. * **Learning Path:** React ํ›…๊ณผ ์ƒํƒœ ๊ด€๋ฆฌ์— ๋Œ€ํ•œ ์ดํ•ด๋ฅผ ๋งˆ์นœ ํ›„, ์„ฑ๋Šฅ ์ตœ์ ํ™”๋ฅผ ์œ„ํ•œ `React.lazy` ํ•™์Šต -> `Suspense`์˜ Fallback ์ฒ˜๋ฆฌ -> React 18 ๋™์‹œ์„ฑ ๊ธฐ๋Šฅ ๋„์ž… ์ˆœ์œผ๋กœ ํ™•์žฅํ•ด ๋‚˜๊ฐ‘๋‹ˆ๋‹ค. * **My Project Relevance:** ๋ฐฉ๋Œ€ํ•œ React ๋ ˆ๊ฑฐ์‹œ ์ฝ”๋“œ๋ฒ ์ด์Šค๋ฅผ ๋ฆฌํŒฉํ† ๋งํ•  ๋•Œ, ๊ฐ€์žฅ ๋ฌด๊ฑฐ์šด ๋ผ์šฐํŠธ๋‚˜ ์ž์ฃผ ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š” ์–ด๋“œ๋ฏผ ๋ทฐ ๋“ฑ์— Suspense๋ฅผ ๋„์ž…ํ•˜์—ฌ ์ดˆ๊ธฐ ๋กœ๋“œ ์‹œ๊ฐ„ ๋ฐ ๋ฒˆ๋“ค ํฌ๊ธฐ ๊ฒฝ๊ณ (์˜ˆ: 500kB ์ดˆ๊ณผ ๊ฒฝ๊ณ )๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๋ฐ ์ ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค [5, 13]. ### Adjacent Topics * [[Error Boundaries]] * ํ™•์žฅ ๋ฐฉํ–ฅ: Suspense๊ฐ€ '๋กœ๋”ฉ ์ค‘' ์ƒํƒœ๋ฅผ ์„ ์–ธ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•œ๋‹ค๋ฉด, Error Boundaries๋Š” ๋ Œ๋”๋ง ์ค‘ ๋˜๋Š” ์ง€์—ฐ ๋กœ๋”ฉ ์‹œ ๋ฐœ์ƒํ•˜๋Š” '์‹คํŒจ/์—๋Ÿฌ' ์ƒํƒœ๋ฅผ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ๋‘ ๊ฐœ๋…์„ ๋‚˜๋ž€ํžˆ ์ ์šฉํ•˜์—ฌ ๊ฒฌ๊ณ ํ•œ UI ์ปดํฌ๋„ŒํŠธ ํŠธ๋ฆฌ๋ฅผ ๊ตฌ์„ฑํ•˜๋Š” ํŒจํ„ด์œผ๋กœ ํ™•์žฅ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค [14-16]. --- *Last updated: 2026-04-30*