๐Loading UI and Streaming
loading.js
๋ React Suspense
๋ฅผ ์ฌ์ฉํด ๋ก๋ฉ UI๋ฅผ ๋ง๋๋๋ฐ ๋์์ด ๋๋ค.
์ด ํ์ผ์ ์ฌ์ฉํ๋ฉด, Segment ๋ด ์ปจํ
์ธ ๊ฐ ๋ก๋๋๋ ๋์ ์ฆ์ ๋ก๋ฉ UI๋ฅผ ํ์ํ ์ ์๋ค.
- ์๋ก์ด ์ปจํ
์ธ ๊ฐ ๋ ๋๋ง์ ์๋ฃํ๋ฉด, ์๋์ผ๋ก ๊ธฐ์กด ๋ก๋ฉ UI์ ๊ต์ฒด ๋๋ค.
๐Instant Loading States
โ
์ฆ์ ๋ก๋ฉ ์ํ๋?
- ๋ด๋น๊ฒ์ด์
์ ์ฆ์ ํ์๋๋ ๋์ฒด UI(Fallback UI) ๋ฅผ ์๋ฏธ
- Ex) ์ค์ผ๋ ํค UI(Skeleton UI), ์คํผ๋(Spinner), ํ์ง ์ด๋ฏธ์ง, ์ ๋ชฉ ๋ฑ
โ
์ ํ์ํ ๊น?
- ์ฌ์ฉ์๊ฐ ์ฑ์ด ๋ฐ์ํ๊ณ ์๋ค๋ ๋๋์ ๋ฐ์ ์ ์๋๋ก ๋์์ค.
์ฆ, ๋ฐ์ดํฐ๊ฐ ๋ก๋๋๋ ๋์ ๋น ํ๋ฉด ๋์ ๋ฏธ๋ฆฌ ์ค๋น๋ UI๋ฅผ ๋ณด์ฌ์ค์ผ๋ก์จ UX๋ฅผ ํฅ์์ํด.

export default function Loading() {
return <LoadingSkeleton />
}
loading.js
๋ ๋์ผํ ํด๋ ๋ด์layout.js
๋ด๋ถ์ ์ค์ฒฉ(Nested)๋๋ค.
- ์๋์ผ๋ก
page.js
๋ฐ ํด๋น ์์ ์ปดํฌ๋ํธ๋ค์ <suspense>
๊ฒฝ๊ณ ์์ wrapํ๋ค.
โ ํน์ segment
๋ฐ์ดํฐ๊ฐ ๋ก๋๋๋ ๋์ loading.js
์์ ์ ์ํ ๋ก๋ฉ UI๊ฐ ๋จผ์ ํ์๋๋ฉฐ, ๋ฐ์ดํฐ ๋ก๋ฉ์ด ์๋ฃ๋๋ฉด ์๋์ผ๋ก ์๋ก์ด ์ปจํ
์ธ ์ ๊ต์ฒด๋๋ค.

Good to know
- ์๋ฒ ์ค์ฌ ๋ผ์ฐํ
(server-centric routing)์ ์ฌ์ฉํ๋๋ผ๋, ๋น ๋ฅธ ๊ฒฝ๋ก ์ ํ ๊ฐ๋ฅ
- ๋ค๋น๊ฒ์ด์
์ ์ปจํ
์ธ ๊ฐ ์์ ํ ๋ก๋๋ ๋๊น์ง ๊ธฐ๋ค๋ฆด ํ์ ์์ด ๋ค๋ฅธ ๊ฒฝ๋ก๋ก ์ด๋ ๊ฐ๋ฅ
- ๊ณต์ ๋ ์ด์์์ ์๋ก์ด ๊ฒฝ๋ก๊ฐ ๋ก๋๋๋ ๋์์๋ ๊ณ์ ์ํธ์์ฉ ํ ์ ์๋ค.
๊ถ์ฅ ์ฌํญ
loading.js
ํ์ผ์ ์ฌ์ฉํด ๋ ์ด์์ ๋ฐ ํ์ด์ง์ ๊ฒฝ๋ก(Segment)์ ๋ก๋ฉ UI๋ฅผ ์ถ๊ฐํ ๊ฒ
Next.js๋ ์ด๋ฅผ ์๋์ผ๋ก ์ต์ ํํจ
๐Streaming with Suspense
loading.js
์ธ์๋, ์ง์ Suspense
๊ฒฝ๊ณ๋ฅผ ์์ฑํด ํน์ UI ์ปดํฌ๋ํธ์ ๋ก์ง ์ํ๋ฅผ ๊ด๋ฆฌํ ์ ์๋ค.
- App Router๋
Suspense
๋ฅผ ํ์ฉํ Streaming์ ์ง์ํ๋ค.
โ ์ฆ, ํ์ด์ง ์ ์ฒด๊ฐ ์๋ ๊ฐ๋ณ ์ปดํฌ๋ํธ์์๋ suspense
๋ฅผ ์ฌ์ฉํด ๋ฐ์ดํฐ ๋ก๋ฉ์ด ๋๋๋ ๋๋ก ๋ ๋๋ง์ ํ ์ ์๋ค.
What is Streaming?
- ์คํธ๋ฆฌ๋ฐ์ด๋ ์๋ฒ์์ ํด๋ผ์ด์ธํธ๋ก ๋ฐ์ดํฐ๋ฅผ ํ๋ฒ์ ์ ์กํ๋ ๊ฒ์ด ์๋๋ผ
์ค๋น๋ ๋ถ๋ถ๋ถํฐ ์ฆ์ ๋ ๋๋งํ๋ฉด์ ์ ์ง์ ์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ๋ ๋ฐฉ์
(ํ์ด์ง์ HTML์ ์์ ์ฒญํฌ๋ก ๋ถ๋ฆฌํด ์ ์ง์ ์ผ๋ก server โ client๋ก ๋ณด๋ธ๋ค.)
- Streaming์ ์ดํดํ๋ ค๋ฉด ๋จผ์ ๊ธฐ์กด์ SSR ๋ฐฉ์๊ณผ ๊ทธ ํ๊ณ๋ฅผ ์์์ผ ํ๋ค.
๊ธฐ์กด SSR(Server-Side Rendering)์ ํ๊ณ
- SSR์์๋ ์ฌ์ฉ์๊ฐ ํ์ด์ง๋ฅผ ๋ณด๊ณ ์ํธ์์ฉํ ์ ์๊ธฐ๊น์ง ๋ค์๊ณผ ๊ฐ์ ๋จ๊ณ๊ฐ ํ์ํ๋ค.
- ์๋ฒ์์ ๋ชจ๋ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ด
- ์๋ฒ๊ฐ HTML์ ๋ ๋๋งํจ
- HTML, CSS, JavaScript๋ฅผ ํด๋ผ์ด์ธํธ๋ก ์ ์กํจ
- HTML๊ณผ CSS๋ฅผ ์ฌ์ฉํด ๋น์ํธ์์ฉ(non-interactive)์ํ์ UI๊ฐ ๋จผ์ ๋ ๋๋ง๋๋ค.
- Hydration์ ์ฌ์ฉํด UI์ ์ํธ์์ฉ์ด ๊ฐ๋ฅํ๊ฒ ๋ง๋ ๋ค.


Streaming์ ์ฅ์
- streaming์ ๊ธด ๋ฐ์ดํฐ ์์ฒญ์ผ๋ก ์ธํด ํ์ด์ง ๋ ๋๋ง์ด ์ง์ฐ๋๋ ๊ฒ์ ๋ฐฉ์งํ๋ ๋ฐ ์ ์ฉํ๋ค.
- TTFB, FCP์ ๋จ์ถํ ์ ์๋ค.
- ๋๋ฆฐ ์ฅ์น์์๋ ์ํธ์์ฉ ๊ฐ๋ฅ ์๊ฐ (TTI)๋ฅผ ๊ฐ์ ํ๋๋ฐ ๋์์ด ๋จ.
- Selective Hydration(์ ํ์ ์ํ) : React๋ ์ฌ์ฉ์ ์ํธ์์ฉ(User Interaction)์ ๋ฐ๋ผ ์ด๋ค ์ปดํฌ๋ํธ๋ฅผ ๋จผ์ ์ํธ์์ฉ์ด ๊ฐ๋ฅํ๊ฒ ํ ์ง ์ฐ์ ์์๋ฅผ ์ ํ๋ค.
import { Suspense } from 'react'
import { PostFeed, Weather } from './Components'
export default function Posts() {
return (
<section>
<Suspense fallback={<p>Loading feed...</p>}>
<PostFeed />
</Suspense>
<Suspense fallback={<p>Loading weather...</p>}>
<Weather />
</Suspense>
</section>
)
}