# [[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*