프리페칭은 Pre(사전에, 미리)-Fetching(불러온다) 즉, 사용자가 현재 보고 있는 페이지에서 링크로 연결된 모든 페이지를 사전에 불러오는 기능이다. 페이지 이동을 빠른 속도로 지체없이 처리하기 위해 만들어진 기능이다.
그런데..! Next.js의 사전렌더링 방식에 대해 알고 있다면 의문이 들 수 있다.
Next.js는 서버가 브라우저에 사전 렌더링된 HTML 페이지를 응답한 후, 후속으로 모든 JS 파일을 번들 파일로 전달한다. 이 때문에 초기 접속 요청이 종료된 이후의 페이지 이동은 서버에 별도의 요청 없이 브라우저 측에서 직접 JavaScript 코드를 실행시켜 컴포넌트를 교체하는 방식(CSR)으로 이루어진다.
CSR을 사용하는데 왜 Pre-Fetching이 필요할까?
Next.js는 모든 컴포넌트를 페이지별로 구분해서 저장해두기 때문이다!
이로 인해 사전 렌더링 과정에서 JS Bundle 파일을 전달할 때, 모든 페이지의 JS 코드가 아닌 현재 페이지에 필요한 JS 코드만 전달된다. 모든 페이지의 JS 파일을 한 번에 전달하면 용량이 너무 커지고, 하이드레이션이 지연될 수 있기 때문이다.
따라서 Next.js는 현재 페이지에 해당하는 JS Bundle 파일만 전달한 후, 이후 페이지 이동을 빠르게 하기 위해 Pre-Fetching 기능을 통해 링크된 페이지들의 JS 파일을 미리 불러와 둔다.
이렇게 하면 하이드레이션을 빠르게 하면서도 초기 접속 이후의 페이지 이동을 원활하게 처리할 수 있다.
⚠️ 개발 모드(npm run dev)에서는 Pre-Fetching이 동작하지 않는다.
Pre-Fetching은 프로덕션 모드에서만 작동하며, 이를 위해서는 다음 명령어로 프로젝트를 실행해야 한다.
npm run build
npm run start
Pre-Fetching 작동 방식
다음은 Pre-Fetching이 기본적으로 작동하는 예시 코드이다.
export default function App({ Component, pageProps }: AppProps) {
const router = useRouter();
const onClickButton = () => {
router.push("/test");
};
return (
<>
<header>
<Link href={"/"}>index</Link>
<Link href={"/search"}>search</Link>
<Link href={"/book/1"}>book/1</Link>
<div>
<button onClick={onClickButton}>/test 페이지로 이동</button>
</div>
</header>
<Component {...pageProps} />
</>
);
}
개발자도구의 네트워크 탭을 확인하면 다음과 같은 차이를 확인할 수 있다.
- <Link> 태그로 연결된 /search, /book/1 페이지 → Pre-Fetching O
- 버튼 클릭으로 연결된 /test 페이지 → Pre-Fetching X
<Link> 컴포넌트는 자동으로 Pre-Fetching이 동작하지만, 프로그래매틱하게 이동하는 페이지는 별도의 설정이 필요하기 때문이다.
Pre-Fetching 비활성화
<Link> 컴포넌트에서 Pre-Fetching을 비활성화하고 싶다면 prefetch={false} 옵션을 사용하면 된다.
<Link href={"/search"} prefetch={false}> search </Link>
이렇게 하면 /search 페이지는 사전에 JS 파일이 로드되지 않는다.
Pre-Fetching 강제 설정
Pre-Fetching이 자동으로 되지 않는 /test 페이지도 사전에 불러오도록 설정하고 싶다면, App 컴포넌트가 화면에 마운트 되었을 때 router.prefetch() 메서드를 통해서 직접 프로그래매틱하게 test 페이지를 프리페칭하도록 코드를 작성하면 된다.
export default function App({ Component, pageProps }: AppProps) {
const router = useRouter();
const onClickButton = () => {
router.push("/test");
};
useEffect(() => {
router.prefetch("/test");
}, []);
return (
<>
<header>
<Link href={"/"}>index</Link>
<Link href={"/search"}>search</Link>
<Link href={"/book/1"}>book/1</Link>
<div>
<button onClick={onClickButton}>/test 페이지로 이동</button>
</div>
</header>
<Component {...pageProps} />
</>
);
}
다시 npm run build 해보면, /test 페이지도 Pre-Fetching 되는 것을 확인할 수 있다.
'Frontend > Next.js' 카테고리의 다른 글
[Next.js] CSS Module (0) | 2025.03.26 |
---|---|
[Next.js] 사전렌더링 (0) | 2025.03.25 |