Skip to content

Prefetching โ€‹

๐Ÿ“˜ Official Docs

Prefetching์€ ์‚ฌ์šฉ์ž๊ฐ€ ์‹ค์ œ๋กœ Route๋ฅผ ์ด๋™ํ•˜๊ธฐ ์ „์— ์ด๋™ํ•  ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ๋Š” Route์˜ ๋ฆฌ์†Œ์Šค๋ฅผ ๋ฏธ๋ฆฌ ์ค€๋น„ํ•˜๋Š” ์„ฑ๋Šฅ ์ตœ์ ํ™” ๋ฐฉ์‹์ด๋‹ค.

Next.js์—์„œ๋Š” ์ฃผ๋กœ Link ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ด์šฉํ•ด ์ž๋™ Prefetching์„ ์ˆ˜ํ–‰ํ•˜๋ฉฐ,
ํ•„์š”ํ•œ ๊ฒฝ์šฐ router.prefetch()๋ฅผ ์ด์šฉํ•ด ์ง์ ‘ Prefetching์„ ์‹คํ–‰ํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

Prefetching์˜ ํ•ต์‹ฌ ๋ชฉ์ ์€ ์ดˆ๊ธฐ ๋กœ๋”ฉ์„ ๋น ๋ฅด๊ฒŒ ํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค๋Š” ์ดํ›„ Navigation ๊ณผ์ •์—์„œ ๋ฐœ์ƒํ•˜๋Š” ๋Œ€๊ธฐ ์‹œ๊ฐ„์„ ์ค„์ด๋Š” ๊ฒƒ์— ์žˆ๋‹ค.


1. Prefetching์ด ํ•„์š”ํ•œ ์ด์œ  โ€‹

Prefetching์ด ์—†๋Š” ์ผ๋ฐ˜์ ์ธ Route ์ด๋™์€ ์‚ฌ์šฉ์ž๊ฐ€ ๋งํฌ๋ฅผ ํด๋ฆญํ•œ ์ดํ›„ ํ•„์š”ํ•œ Route๋ฅผ ์š”์ฒญํ•œ๋‹ค.

text
์‚ฌ์šฉ์ž Click
     โ†“
Route ์š”์ฒญ
     โ†“
์‘๋‹ต ๋Œ€๊ธฐ
     โ†“
ํ•„์š”ํ•œ ๋ฆฌ์†Œ์Šค ์ฒ˜๋ฆฌ
     โ†“
ํ™”๋ฉด ์ „ํ™˜

์‚ฌ์šฉ์ž๊ฐ€ ํด๋ฆญํ•œ ์ดํ›„ ์š”์ฒญ๊ณผ ์ฒ˜๋ฆฌ๊ฐ€ ์‹œ์ž‘๋˜๊ธฐ ๋•Œ๋ฌธ์— ๋„คํŠธ์›Œํฌ ์ƒํƒœ๋‚˜ ์„œ๋ฒ„ ์ฒ˜๋ฆฌ ์‹œ๊ฐ„์— ๋”ฐ๋ผ ํŽ˜์ด์ง€ ์ด๋™์ด ์ง€์—ฐ๋  ์ˆ˜ ์žˆ๋‹ค. Prefetching์€ ์ด๋Ÿฌํ•œ ๋Œ€๊ธฐ ์‹œ๊ฐ„์„ ์ค„์ด๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ์ž๊ฐ€ ์ด๋™ํ•˜๊ธฐ ์ „์— Route๋ฅผ ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ๋ฏธ๋ฆฌ ์ค€๋น„ํ•œ๋‹ค.

text
Route Prefetch
      โ†“
์‚ฌ์šฉ์ž Click
      โ†“
์ค€๋น„๋œ ์ •๋ณด ์‚ฌ์šฉ
      โ†“
๋น ๋ฅธ ํ™”๋ฉด ์ „ํ™˜

๋”ฐ๋ผ์„œ ์‚ฌ์šฉ์ž๊ฐ€ ์‹ค์ œ๋กœ ํŽ˜์ด์ง€๋ฅผ ์ด๋™ํ•˜๋Š” ์‹œ์ ์—๋Š” ์ด๋ฏธ ํ•„์š”ํ•œ ์ •๋ณด์˜ ์ผ๋ถ€ ๋˜๋Š” ์ „์ฒด๊ฐ€ ์ค€๋น„๋˜์–ด ์žˆ์„ ์ˆ˜ ์žˆ๋‹ค.


์ผ๋ฐ˜ ํŽ˜์ด์ง€ ์ด๋™ vs Prefetching โ€‹

๊ตฌ๋ถ„์ผ๋ฐ˜ ์ด๋™Prefetching
์š”์ฒญ ์‹œ์ ์ฃผ๋กœ ํด๋ฆญ ์ดํ›„์ผ๋ถ€ ๋ฆฌ์†Œ์Šค๋ฅผ ํด๋ฆญ ์ „
๋Œ€๊ธฐ ์‹œ๊ฐ„๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Œ์ค„์–ด๋“ค ์ˆ˜ ์žˆ์Œ
UX์ „ํ™˜ ๋Œ€๊ธฐ ๊ฐ€๋Šฅ๋” ๋น ๋ฅธ ์ „ํ™˜ ๊ธฐ๋Œ€

Next.js ํŽ˜์ด์ง€ ์ „ํ™˜์ด SPA์ฒ˜๋Ÿผ ๋А๊ปด์ง€๋Š” ํ•ต์‹ฌ ์ด์œ  ์ค‘ ํ•˜๋‚˜๋‹ค.


Code Splitting๊ณผ Prefetching โ€‹

Prefetching์„ ์ดํ•ดํ•˜๋ ค๋ฉด Code Splitting๊ณผ์˜ ์ฐจ์ด๋ฅผ ํ•จ๊ป˜ ์ดํ•ดํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.
Next.js๋Š” Route๋ฅผ ๊ธฐ์ค€์œผ๋กœ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ฝ”๋“œ๋ฅผ ๋ถ„๋ฆฌํ•˜์—ฌ ์ฒ˜์Œ๋ถ€ํ„ฐ ๋ชจ๋“  Route์˜ JavaScript๋ฅผ ํ•œ ๋ฒˆ์— ํด๋ผ์ด์–ธํŠธ๋กœ ์ „๋‹ฌํ•˜์ง€ ์•Š๋Š”๋‹ค.

text
์ „์ฒด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜
โ”œโ”€ /home
โ”‚   โ””โ”€ ํ•„์š”ํ•œ ์ฝ”๋“œ
โ”‚
โ”œโ”€ /posts
โ”‚   โ””โ”€ ํ•„์š”ํ•œ ์ฝ”๋“œ
โ”‚
โ””โ”€ /mypage
    โ””โ”€ ํ•„์š”ํ•œ ์ฝ”๋“œ

ํ˜„์žฌ /home์— ์ ‘์†ํ•œ ์‚ฌ์šฉ์ž๊ฐ€ ์žˆ๋‹ค๋ฉด ์ดˆ๊ธฐ ๋กœ๋”ฉ์—์„œ๋Š” ํ˜„์žฌ Route์— ํ•„์š”ํ•œ ๋ฆฌ์†Œ์Šค๋ฅผ ์šฐ์„ ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๋Ÿฌํ•œ ๊ตฌ์กฐ๋ฅผ ํ†ตํ•ด ์ดˆ๊ธฐ ๋กœ๋”ฉ ์‹œ ๋ถˆํ•„์š”ํ•œ JavaScript ์ „๋‹ฌ์„ ์ค„์ผ ์ˆ˜ ์žˆ๋‹ค.

ํ•˜์ง€๋งŒ Code Splitting์œผ๋กœ Route๋ฅผ ๋‚˜๋ˆ„๋ฉด ์‚ฌ์šฉ์ž๊ฐ€ ์•„์ง ๋ฐฉ๋ฌธํ•˜์ง€ ์•Š์€ Route์˜ ๋ฆฌ์†Œ์Šค๋Š” ํ•„์š”ํ•  ๋•Œ ์ƒˆ๋กญ๊ฒŒ ๊ฐ€์ ธ์™€์•ผ ํ•œ๋‹ค. Prefetching์€ ์ด ๋ถ€๋ถ„์„ ๋ณด์™„ํ•œ๋‹ค.

  • Code Splitting โ†’ ์ฒ˜์Œ๋ถ€ํ„ฐ ๋ชจ๋“  Route๋ฅผ ๋กœ๋“œํ•˜์ง€ ์•Š์Œ โ†’ ์ดˆ๊ธฐ ๋กœ๋”ฉ ๋ถ€๋‹ด ๊ฐ์†Œ
  • Prefetching โ†’ ์ด๋™ ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ๋Š” Route๋ฅผ ๋ฏธ๋ฆฌ ์ค€๋น„ โ†’ Navigation ๋Œ€๊ธฐ ์‹œ๊ฐ„ ๊ฐ์†Œ

์ฆ‰, Code Splitting์€ ์ดˆ๊ธฐ ๋กœ๋”ฉ ๋น„์šฉ์„ ์ค„์ด๊ณ ,
Prefetching์€ ์ดํ›„ ํŽ˜์ด์ง€ ์ด๋™์—์„œ ๋ฐœ์ƒํ•˜๋Š” ๋Œ€๊ธฐ ์‹œ๊ฐ„์„ ์ค„์ด๋Š” ์—ญํ• ์„ ํ•œ๋‹ค.


2. Automatic Prefetching โ€‹

Next.js์˜ Link ์ปดํฌ๋„ŒํŠธ๋Š” Prefetching์„ ์ง€์›ํ•œ๋‹ค.

tsx
import Link from "next/link";

export default function Page() {
  return <Link href="/posts/1">๊ฒŒ์‹œ๊ธ€ ๋ณด๊ธฐ</Link>;
}

Production ํ™˜๊ฒฝ์—์„œ Link๊ฐ€ ์‚ฌ์šฉ์ž์˜ Viewport์— ๋“ค์–ด์˜ค๋Š” ๋“ฑ์˜ ์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜๋ฉด Next.js๋Š” ํ•ด๋‹น Route๋ฅผ ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ๋ฏธ๋ฆฌ ์ค€๋น„ํ•  ์ˆ˜ ์žˆ๋‹ค.

text
<Link href="/posts/1" />
          โ†“
Viewport ์ง„์ž…
          โ†“
Route Prefetch
          โ†“
์‚ฌ์šฉ์ž Click
          โ†“
Client-side Navigation

์‚ฌ์šฉ์ž๊ฐ€ ์‹ค์ œ ๋งํฌ๋ฅผ ํด๋ฆญํ•˜๊ธฐ ์ „์— Route๊ฐ€ ์ค€๋น„๋˜๊ธฐ ๋•Œ๋ฌธ์— ๋น ๋ฅธ ํŽ˜์ด์ง€ ์ „ํ™˜์ด ๊ฐ€๋Šฅํ•ด์ง„๋‹ค.


Production ํ™˜๊ฒฝ์—์„œ ๋™์ž‘ โ€‹

์ž๋™ Prefetching์€ Production ํ™˜๊ฒฝ์—์„œ ํ™œ์„ฑํ™”๋œ๋‹ค.
๋”ฐ๋ผ์„œ ์‹ค์ œ Prefetching ๋™์ž‘์„ ํ™•์ธํ•˜๋ ค๋ฉด Production Build๋กœ ์‹คํ–‰ํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.

๊ฐœ๋ฐœ ํ™˜๊ฒฝ์—์„œ๋Š” ๊ฐœ๋ฐœ ํŽธ์˜์„ฑ๊ณผ ๋ถˆํ•„์š”ํ•œ ์š”์ฒญ ๋ฐฉ์ง€๋ฅผ ์œ„ํ•ด Production๊ณผ ๋™์ผํ•œ Prefetching ๋™์ž‘์„ ํ™•์ธํ•˜๊ธฐ ์–ด๋ ค์šธ ์ˆ˜ ์žˆ๋‹ค.


3. Page Router์˜ Prefetching โ€‹

Page Router์—์„œ๋„ Link๋ฅผ ์ด์šฉํ•œ ์ž๋™ Prefetching์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

tsx
import Link from "next/link";

export default function Page() {
  return <Link href="/posts/1">๊ฒŒ์‹œ๊ธ€ ๋ณด๊ธฐ</Link>;
}

Page Router์˜ Link๋Š” ์—ฐ๊ฒฐ๋œ Route์— ํ•„์š”ํ•œ ํŽ˜์ด์ง€ ์ฝ”๋“œ์™€ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฏธ๋ฆฌ ์ค€๋น„ํ•˜์—ฌ Client-side Navigation ์†๋„๋ฅผ ๊ฐœ์„ ํ•œ๋‹ค.

text
pages
โ”œโ”€ index.tsx
โ”œโ”€ posts
โ”‚   โ””โ”€ [id].tsx
โ””โ”€ mypage.tsx

์˜ˆ๋ฅผ ๋“ค์–ด /posts/1๋กœ ์ด๋™ํ•˜๋Š” Link๊ฐ€ ์žˆ๋‹ค๋ฉด Next.js๋Š” ํ•ด๋‹น ํŽ˜์ด์ง€์— ํ•„์š”ํ•œ ๋ฆฌ์†Œ์Šค๋ฅผ ๋ฏธ๋ฆฌ ์ค€๋น„ํ•  ์ˆ˜ ์žˆ๋‹ค.


Programmatic Prefetching โ€‹

Link๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” Programmatic Navigation์—์„œ๋Š” router.prefetch()๋ฅผ ์ด์šฉํ•ด Route๋ฅผ ์ง์ ‘ ๋ฏธ๋ฆฌ ์ค€๋น„ํ•  ์ˆ˜ ์žˆ๋‹ค.

tsx
import { useEffect } from "react";
import { useRouter } from "next/router";

export default function Page() {
  const router = useRouter();

  useEffect(() => {
    router.prefetch("/dashboard");
  }, [router]);

  const handleClick = () => {
    router.push("/dashboard");
  };

  return <button onClick={handleClick}>Dashboard</button>;
}

Link๊ฐ€ ์ž๋™์œผ๋กœ Prefetching์„ ์ฒ˜๋ฆฌํ•ด ์ฃผ๋Š” ๊ฒฝ์šฐ์—๋Š” ๋ณ„๋„๋กœ router.prefetch()๋ฅผ ์‚ฌ์šฉํ•  ํ•„์š”๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ๋‹ค.


Prefetching ๋น„ํ™œ์„ฑํ™” โ€‹

Page Router์˜ Link์—์„œ๋Š” prefetch={false}๋ฅผ ์ด์šฉํ•ด Viewport ๊ธฐ๋ฐ˜ Prefetching์„ ๋น„ํ™œ์„ฑํ™”ํ•  ์ˆ˜ ์žˆ๋‹ค.

tsx
<Link href="/search" prefetch={false}>
  Search
</Link>

๋‹ค๋งŒ Page Router์—์„œ๋Š” prefetch={false}๋ฅผ ์‚ฌ์šฉํ•ด๋„ Hover ์‹œ Prefetch๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค.
๋”ฐ๋ผ์„œ Page Router์™€ App Router์˜ prefetch={false} ๋™์ž‘์—๋Š” ์ฐจ์ด๊ฐ€ ์žˆ๋‹ค.


4. App Router์˜ Prefetching โ€‹

App Router์—์„œ๋„ Link๋ฅผ ์ด์šฉํ•ด Route๋ฅผ ์ž๋™ Prefetchํ•  ์ˆ˜ ์žˆ๋‹ค.

tsx
import Link from "next/link";

export default function Page() {
  return <Link href="/posts/1">๊ฒŒ์‹œ๊ธ€ ๋ณด๊ธฐ</Link>;
}

App Router์—์„œ๋Š” Server Component๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— Prefetching ๋Œ€์ƒ์ด ๋‹จ์ˆœํžˆ JavaScript Bundle๋งŒ์„ ์˜๋ฏธํ•˜์ง€ ์•Š๋Š”๋‹ค. Route์— ๋”ฐ๋ผ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ •๋ณด๊ฐ€ ๋ฏธ๋ฆฌ ์ค€๋น„๋  ์ˆ˜ ์žˆ๋‹ค.

text
Route
โ”œโ”€ RSC Payload
โ”œโ”€ Client Component JavaScript
โ””โ”€ Route ๋ Œ๋”๋ง์— ํ•„์š”ํ•œ ์ •๋ณด

Prefetch ๋ฒ”์œ„๋Š” Route๊ฐ€ Static์ธ์ง€ Dynamic์ธ์ง€์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์งˆ ์ˆ˜ ์žˆ๋‹ค.

Prefetching์ด ํ•ญ์ƒ ๋ฐ์ดํ„ฐ๊นŒ์ง€ ์ „๋ถ€ ๊ฐ€์ ธ์˜ค๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค.
(๋ผ์šฐํ„ฐ / fetch ๋ฐฉ์‹ / ์บ์‹œ ์ „๋žต์— ๋”ฐ๋ผ ๋‹ค๋ฆ„)


Static Route โ€‹

์ •์ ์œผ๋กœ ์ค€๋น„ํ•  ์ˆ˜ ์žˆ๋Š” Route๋Š” ์ „์ฒด Route๋ฅผ Prefetchํ•  ์ˆ˜ ์žˆ๋‹ค.

text
Link๊ฐ€ Viewport์— ์ง„์ž…
        โ†“
์ „์ฒด Route Prefetch
        โ†“
์‚ฌ์šฉ์ž Click
        โ†“
์ค€๋น„๋œ Route ์‚ฌ์šฉ

ex.

less
app
โ””โ”€ about
   โ””โ”€ page.tsx

/about์ด Static Route๋ผ๋ฉด Next.js๋Š” ํ•ด๋‹น Route๋ฅผ ๋ฏธ๋ฆฌ ์ค€๋น„ํ•˜์—ฌ ์ดํ›„ Navigation์— ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.


Dynamic Route โ€‹

Dynamic Route๋Š” ์š”์ฒญ ์‹œ์ ์— ์„œ๋ฒ„ ์ž‘์—…์ด ํ•„์š”ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ํ•ญ์ƒ ์ „์ฒด Route๊ฐ€ ๋ฏธ๋ฆฌ ์ค€๋น„๋˜๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค.

less
app
โ””โ”€ blog
   โ””โ”€ [slug]
      โ”œโ”€ page.tsx
      โ””โ”€ loading.tsx

๊ธฐ๋ณธ Prefetch ๋™์ž‘์—์„œ๋Š” loading.tsx์™€ ๊ฐ™์€ Loading Boundary๊ฐ€ ์กด์žฌํ•  ๊ฒฝ์šฐ ํ•ด๋‹น Boundary๊นŒ์ง€์˜ Route ์ผ๋ถ€๋ฅผ ๋ฏธ๋ฆฌ ์ค€๋น„ํ•  ์ˆ˜ ์žˆ๋‹ค.

text
Shared Layout
      +
Loading UI
      โ†“
๋ฏธ๋ฆฌ Prefetch

์‹ค์ œ Dynamic Content
      โ†“
Navigation ์ดํ›„ ์„œ๋ฒ„์—์„œ ์ฒ˜๋ฆฌ

์ด๋ฅผ ํ†ตํ•ด ์ „์ฒด Dynamic Route๊ฐ€ ์ค€๋น„๋  ๋•Œ๊นŒ์ง€ ์•„๋ฌด ํ™”๋ฉด๋„ ๋ณด์—ฌ์ฃผ์ง€ ์•Š๊ณ  ๊ธฐ๋‹ค๋ฆฌ๋Š” ๋Œ€์‹ , ์ค€๋น„๋œ Layout์ด๋‚˜ Loading UI๋ฅผ ๋จผ์ € ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.


prefetch ์˜ต์…˜ โ€‹

App Router์˜ Link์—์„œ๋Š” prefetch ๊ฐ’์„ ์ด์šฉํ•ด Prefetch ๋™์ž‘์„ ์ œ์–ดํ•  ์ˆ˜ ์žˆ๋‹ค.

tsx
<Link href="/dashboard">Dashboard</Link>

๊ธฐ๋ณธ๊ฐ’์€ ์ž๋™ ๋™์ž‘์ด๋ฉฐ Route ํŠน์„ฑ์— ๋”ฐ๋ผ Prefetch ๋ฒ”์œ„๊ฐ€ ๋‹ฌ๋ผ์ง„๋‹ค.

  • Static Route โ†’ ์ „์ฒด Route Prefetch ๊ฐ€๋Šฅ
  • Dynamic Route โ†’ loading.tsx Boundary๊นŒ์ง€ Partial Prefetch ๊ฐ€๋Šฅ

์ „์ฒด Route๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ Prefetchํ•˜๋„๋ก ์„ค์ •ํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

tsx
<Link href="/dashboard" prefetch={true}>
  Dashboard
</Link>

๋ฐ˜๋Œ€๋กœ Prefetching์„ ์™„์ „ํžˆ ๋น„ํ™œ์„ฑํ™”ํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

tsx
<Link href="/dashboard" prefetch={false}>
  Dashboard
</Link>

App Router์—์„œ prefetch={false}๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด Viewport ์ง„์ž…์ด๋‚˜ Hover์— ์˜ํ•œ ์ž๋™ Prefetching์ด ์ˆ˜ํ–‰๋˜์ง€ ์•Š๋Š”๋‹ค.


5. Client-side Router Cache โ€‹

App Router์—์„œ๋Š” Prefetching์ด๋‚˜ Navigation ๊ณผ์ •์—์„œ ๊ฐ€์ ธ์˜จ RSC Payload์™€ Route Segment ์ •๋ณด๋ฅผ Client-side Router Cache์— ์ €์žฅํ•˜๊ณ , ์ดํ›„ Navigation์—์„œ ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

๋”ฐ๋ผ์„œ ์ด๋ฏธ Prefetch๋˜์—ˆ๊ฑฐ๋‚˜ ๋ฐฉ๋ฌธํ–ˆ๋˜ Route๋กœ ๋‹ค์‹œ ์ด๋™ํ•  ๋•Œ ์บ์‹œ๋œ ์ •๋ณด๋ฅผ ํ™œ์šฉํ•ด ๋ถˆํ•„์š”ํ•œ ์š”์ฒญ๊ณผ Navigation ๋Œ€๊ธฐ ์‹œ๊ฐ„์„ ์ค„์ผ ์ˆ˜ ์žˆ๋‹ค.

๋‹ค๋งŒ Cache์˜ ์œ ์ง€ ๋ฒ”์œ„์™€ ์‹œ๊ฐ„์€ Route ํŠน์„ฑ์ด๋‚˜ Next.js ๋ฒ„์ „ ๋ฐ ์„ค์ •์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์งˆ ์ˆ˜ ์žˆ๋‹ค.


6. App Router์˜ Manual Prefetching โ€‹

App Router์—์„œ๋„ router.prefetch()๋ฅผ ์ด์šฉํ•ด Route๋ฅผ ์ง์ ‘ Prefetchํ•  ์ˆ˜ ์žˆ๋‹ค.

tsx
"use client";

import { useRouter } from "next/navigation";

export default function Page() {
  const router = useRouter();

  const handlePrefetch = () => {
    router.prefetch("/pricing");
  };

  return <button onMouseEnter={handlePrefetch}>Pricing</button>;
}

์ด ๋ฐฉ์‹์€ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒฝ์šฐ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

  • Viewport ๋ฐ–์— ์žˆ๋Š” Route๋ฅผ ๋ฏธ๋ฆฌ ์ค€๋น„ํ•˜๊ณ  ์‹ถ์€ ๊ฒฝ์šฐ
  • Hover ์‹œ์ ์—๋งŒ Prefetchํ•˜๊ณ  ์‹ถ์€ ๊ฒฝ์šฐ
  • ํŠน์ • ์‚ฌ์šฉ์ž ํ–‰๋™ ์ดํ›„ Prefetchํ•˜๊ณ  ์‹ถ์€ ๊ฒฝ์šฐ
  • ๋ถ„์„ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ๋‹ค์Œ Route๋ฅผ ์˜ˆ์ธกํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒฝ์šฐ

์ผ๋ฐ˜์ ์ธ ๋งํฌ ์ด๋™์—์„œ๋Š” Link์˜ ์ž๋™ Prefetching์„ ์šฐ์„  ์‚ฌ์šฉํ•˜๊ณ , ๊ธฐ๋ณธ ๋™์ž‘๋งŒ์œผ๋กœ ๋ถ€์กฑํ•œ ๊ฒฝ์šฐ Manual Prefetching์„ ๊ณ ๋ คํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.


Hover ๊ธฐ๋ฐ˜ Prefetching โ€‹

Viewport์— ๋“ค์–ด์˜ค๋Š” ๋ชจ๋“  Link๋ฅผ ๋ฏธ๋ฆฌ ๊ฐ€์ ธ์˜ค๋Š” ๋Œ€์‹  ์‚ฌ์šฉ์ž๊ฐ€ ์‹ค์ œ๋กœ ๊ด€์‹ฌ์„ ๋ณด์ธ Link๋งŒ Prefetchํ•˜๋„๋ก ๊ตฌํ˜„ํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

tsx
"use client";

import { useRouter } from "next/navigation";

export default function PricingButton() {
  const router = useRouter();

  return (
    <button
      onMouseEnter={() => router.prefetch("/pricing")}
      onClick={() => router.push("/pricing")}
    >
      Pricing
    </button>
  );
}

์ด ๋ฐฉ์‹์€ ๋ถˆํ•„์š”ํ•œ Prefetch ์š”์ฒญ์„ ์ค„์ด๋ฉด์„œ ์‚ฌ์šฉ์ž๊ฐ€ ์‹ค์ œ๋กœ ์ด๋™ํ•  ๊ฐ€๋Šฅ์„ฑ์ด ๋†’์•„์ง„ ์‹œ์ ์— Route๋ฅผ ๋ฏธ๋ฆฌ ์ค€๋น„ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์žฅ์ ์ด ์žˆ๋‹ค.


7. Prefetching ๋น„ํ™œ์„ฑํ™” โ€‹

Prefetching์ด ํ•ญ์ƒ ํ•„์š”ํ•œ ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค.

๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒฝ์šฐ์—๋Š” Prefetch ๋ฒ”์œ„๋ฅผ ์ค„์ด๊ฑฐ๋‚˜ ๋น„ํ™œ์„ฑํ™”๋ฅผ ๊ณ ๋ คํ•  ์ˆ˜ ์žˆ๋‹ค.

  • ์‚ฌ์šฉ์ž๊ฐ€ ์ด๋™ํ•  ๊ฐ€๋Šฅ์„ฑ์ด ๋งค์šฐ ๋‚ฎ์€ Route
  • Link๊ฐ€ ๋งค์šฐ ๋งŽ์ด ์กด์žฌํ•˜๋Š” ํ™”๋ฉด
  • ๋„คํŠธ์›Œํฌ ์‚ฌ์šฉ๋Ÿ‰์„ ์ค„์—ฌ์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ
  • ์‚ฌ์šฉ์ž์˜ ํ–‰๋™ ์ดํ›„์—๋งŒ ์˜๋ฏธ๊ฐ€ ์ƒ๊ธฐ๋Š” Route

Prefetch๋ฅผ ์ œํ•œํ•˜๋ฉด ๋ถˆํ•„์š”ํ•œ ๋„คํŠธ์›Œํฌ ์š”์ฒญ์„ ์ค„์ผ ์ˆ˜ ์žˆ์ง€๋งŒ,
์‹ค์ œ Navigation ์‹œ ํ•„์š”ํ•œ ์ •๋ณด๋ฅผ ์ƒˆ๋กญ๊ฒŒ ๊ฐ€์ ธ์™€์•ผ ํ•˜๋ฏ€๋กœ ๋Œ€๊ธฐ ์‹œ๊ฐ„์ด ์ฆ๊ฐ€ํ•  ์ˆ˜ ์žˆ๋‹ค.

  • Prefetch ์ ๊ทน ํ™œ์šฉ โ†’ ๋น ๋ฅธ Navigation / ๋„คํŠธ์›Œํฌ ์‚ฌ์šฉ๋Ÿ‰ ์ฆ๊ฐ€ ๊ฐ€๋Šฅ
  • Prefetch ์ œํ•œ โ†’ ๋„คํŠธ์›Œํฌ ์š”์ฒญ ๊ฐ์†Œ / Navigation ๋Œ€๊ธฐ ์‹œ๊ฐ„ ์ฆ๊ฐ€ ๊ฐ€๋Šฅ

8. Page Router์™€ App Router ๋น„๊ต โ€‹

๊ตฌ๋ถ„Page RouterApp Router
์ž๋™ PrefetchLinkLink
Manual Prefetchnext/routernext/navigation
์ฃผ์š” Prefetch ๋Œ€์ƒํŽ˜์ด์ง€ ์ฝ”๋“œ ๋ฐ ๊ด€๋ จ ๋ฐ์ดํ„ฐRSC Payload, Client JS ๋ฐ Route ์ •๋ณด
Static / Dynamic ๊ตฌ๋ถ„์žˆ์ŒPrefetch ๋ฒ”์œ„์— ์ง์ ‘์ ์ธ ์˜ํ–ฅ
Partial Prefetch์ œํ•œ์ loading.tsx Boundary ํ™œ์šฉ ๊ฐ€๋Šฅ
prefetch={false}Viewport Prefetch ๋น„ํ™œ์„ฑํ™”, Hover Prefetch ๊ฐ€๋Šฅ์ž๋™ Prefetch ๋น„ํ™œ์„ฑํ™”

๋‘ Router ๋ชจ๋‘ Prefetching์„ ์ œ๊ณตํ•˜์ง€๋งŒ App Router์—์„œ๋Š” Server Component์™€ Streaming ๊ตฌ์กฐ๊ฐ€ ํ•จ๊ป˜ ์‚ฌ์šฉ๋˜๊ธฐ ๋•Œ๋ฌธ์— Prefetching์˜ ์—ญํ• ์ด ๋” Route Segment ์ค‘์‹ฌ์œผ๋กœ ํ™•์žฅ๋œ๋‹ค.


์ •๋ฆฌ โ€‹

Next.js์˜ Prefetching์€ ์‚ฌ์šฉ์ž๊ฐ€ Route๋ฅผ ์ด๋™ํ•˜๊ธฐ ์ „์— ํ•„์š”ํ•œ ์ •๋ณด๋ฅผ ๋ฏธ๋ฆฌ ์ค€๋น„ํ•˜์—ฌ Navigation ๋Œ€๊ธฐ ์‹œ๊ฐ„์„ ์ค„์ด๋Š” ๊ธฐ๋Šฅ์ด๋‹ค.

  • Code Splitting โ†’ ์ดˆ๊ธฐ Route์— ํ•„์š”ํ•œ ๋ฆฌ์†Œ์Šค ์ค‘์‹ฌ์œผ๋กœ ๋กœ๋“œ โ†’ ์ดˆ๊ธฐ ๋กœ๋”ฉ ๋ถ€๋‹ด ๊ฐ์†Œ
  • Prefetching โ†’ ์ดํ›„ ์ด๋™ํ•  ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ๋Š” Route๋ฅผ ๋ฏธ๋ฆฌ ์ค€๋น„ โ†’ Navigation ๋Œ€๊ธฐ ์‹œ๊ฐ„ ๊ฐ์†Œ

Next.js์—์„œ๋Š” Link๋ฅผ ์ด์šฉํ•œ Automatic Prefetching์„ ๊ธฐ๋ณธ์ ์œผ๋กœ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ํ•„์š”ํ•œ ๊ฒฝ์šฐ router.prefetch()๋ฅผ ์ด์šฉํ•ด Manual Prefetching์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.

Page Router์—์„œ๋Š” ํŽ˜์ด์ง€ ์ฝ”๋“œ์™€ ๊ด€๋ จ ๋ฐ์ดํ„ฐ๋ฅผ ์ค‘์‹ฌ์œผ๋กœ Prefetching์ด ์ด๋ฃจ์–ด์ง€๊ณ , App Router์—์„œ๋Š” Server Component ๊ตฌ์กฐ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ RSC Payload์™€ Route Segment ๋“ฑ์„ ํ™œ์šฉํ•œ๋‹ค.

ํŠนํžˆ App Router์—์„œ๋Š” Static Route์™€ Dynamic Route์˜ ํŠน์„ฑ, loading.tsx, Client-side Router Cache, Streaming ๋“ฑ์ด ํ•จ๊ป˜ ์ž‘๋™ํ•˜๋ฉด์„œ ๋น ๋ฅธ Client-side Navigation์„ ๊ตฌํ˜„ํ•œ๋‹ค.

๋”ฐ๋ผ์„œ Prefetching์€ ์ดˆ๊ธฐ ๋กœ๋”ฉ ์ž์ฒด๋ฅผ ๋น ๋ฅด๊ฒŒ ๋งŒ๋“œ๋Š” ๊ธฐ๋Šฅ์ด๋ผ๊ธฐ๋ณด๋‹ค, Code Splitting ์ดํ›„ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” Route ์ด๋™ ์ง€์—ฐ์„ ์ค„์—ฌ์ฃผ๋Š” Navigation ์ตœ์ ํ™” ์ „๋žต์œผ๋กœ ์ดํ•ดํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.