본문 바로가기

Frameworks/Next.js

[Next.js] 프리페칭(Pre-fetching)

728x90

 

 

Next.js에서 프리페칭 하는 법을 알아보자!

 

 


 

 

 프리페칭(Pre-fetching) 

 

Pre-Fetching : 사전에 미리 불러온다  페이지를 사전에 불러온다!

현재 사용자가 보고 있는 페이지에서, 이동할 가능성이 있는 모든 페이지들을 사전에 미리 다 불러놓는 기능이다.

프리페칭을 통해, 사용자가 다른 페이지로 이동하는 링크를 클릭하기 전에, 현재 페이지에서 이동이 가능한 모든 페이지에 필요한 데이터를 미리 불러와놓음으로써, 페이지 이동을 매우 빠른 속도로 지체 없이 처리해줄 수 있게 된다.

 

 

HTML이 화면에 렌더링되고 난 이후, 초기 요청 시, 모든 페이지에 대한 자바스크립트 파일이 다 전달되는 것이 아니라,
현재 접속 요청이 발생한 페이지에 해당하는 자바스크립트 번들 파일만 전달된다.

그리고 페이지에 접속한 이후에는, 프리패칭이라는 기능을 통해서, 현재 페이지에서 이동할 수 있는 모든 페이지들에 대한 자바스크립트 코드를 사전에 미리 다 불러와서, 페이지 이동을 빠르게 할 수 있게 된다.

 

 

Next 앱은 npm run dev (개발모드)로 가동할 때는 프리패칭이 동작하지 않는다.

그래서 프리패칭 동작을 확인하려면 빌드에서 실행하는 프로덕션 모드로 실행해야한다.

그래서 터미널에서 개발모드를 종료하고, npm run build를 해서 프로젝트를 빌드하면 빌드 결과가 나오게 된다.

 

 

페이지들 별로 스플리팅이 잘 된 것을 볼 수 있다.

npm run start로 프로덕션 모드로 실행을 한 뒤 네트워크 탭을 들어가서 search나 book 요청을 클릭해서 들어가보면,

search나 book 페이지에 필요한 JS 코드를 프리페칭해서 불러와 놓은 것을 볼 수 있다.

 

 

search 페이지

 

book 페이지

 

그래서 search 페이지와 book 페이지는 프리페칭이 완료된 상태이기 때문에, 각 페이지로 이동한다고 하더라도 네트워크 탭에는 아무런 요청도 추가적으로 발생하지 않는다.

 

import "@/styles/globals.css";
import type { AppProps } from "next/app";
import Link from "next/link";
import { useRouter } from "next/router";

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>
          <button onClick={onClickButton}>/test 페이지로 이동</button>
        </div>
      </header>
      <Component {...pageProps} />
    </>
  )
}

 

그러나 여기서 test 페이지는 예외적으로 프리패칭이 이뤄지지 않는다. 

test 페이지는 Link 컴포넌트로 명시된 경로가 아닌, 프로그래메틱하게 페이지를 이동하도록 설정해뒀기 때문이다. 

test 페이지의 경우에도 프리페칭을 하고 싶다면, App 컴포넌트가 화면에 마운트 되었을때, router 객체의 특정 메서드를 통해서 직접 프로그래메틱하게 이 테스트 페이지를 프리패칭하도록 아래와 같이 코드를 작성해주면 된다.

 

import "@/styles/globals.css";
import type { AppProps } from "next/app";
import Link from "next/link";
import { useRouter } from "next/router";
import { useEffect } from "react";

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} />
    </>
  )
}

 

 

  만약에 Link 컴포넌트로 명시된 search 페이지의 프리패칭을 해제하고 싶다면, 아래와 같이 prefetch={false} 를 설정해주면 된다.

 

  return (
    <>
      <header>
        <Link href={"/"}>index</Link>
        &nbsp;
        <Link href={"/search"} prefetch={false}> search</Link> // 프리패칭 해제
        &nbsp;
        <Link href={"/book/1"}>book/1</Link>
        <div>
          <button onClick={onClickButton}>/test 페이지로 이동</button>
        </div>
      </header>
      <Component {...pageProps} />
    </>
  )
}

 

728x90