티스토리 뷰
✅ 프리페칭 (Pre-fetching)
빠른 페이지 이동을 위해 현재 사용자가 보고있는 페이지 내에서 이동할 가능성이 있는 모든 페이지들을 사전에 미리 불러놓는 기능이다.
그런데 여기서 생각해볼 것이 있다.
Next.js는 초기 접속 요청이 발생했을 때 사전렌더링이 되고 이후 서버가 모든 JS파일을 번들 형태로 브라우저에게 전달해준다.
그리고 초기 접속 요청이 종료된 이후에 발생하는 페이지 이동은 서버에게 추가적인 요청없이
브라우저가 직접 자바스크립트 코드를 실행시켜서 필요한 컴포넌트를 교체하는 CSR 방식으로 이루어진다.
그럼 페이지를 이동시키게 되더라도 사실상 브라우저가 서버에게 추가적인 리소스를 요청할 필요가 없는데
왜 프리 페칭 같은 기능이 필요할까?
Next.js는 next 앱 안에 작성한 모든 js코드(react 컴포넌트)를 자동으로 페이지 별로 분리해서 미리 저장해 놓는다.
그리고 사실 Next.js는 사전렌더링 과정에서 서버가 브라우저에게 JS번들 파일을 전달할 때
모든 페이지에 필요한 js코드가 전달하는 것이 아니라 현재 페이지에 필요한 js코드만 전달한다.
초기접속 요청이 있을 때마다 모든 페이지의 js번들파일을 전달할 경우 용량이 너무 커지게 되며 hydraiton(수화) 시간이 늦어져
결론적으로 TTI가 늦어지게 되는 문제가 발생할 수 있기 때문이다.
이렇게 되면 초기접속 이후 페이지를 이동하려고 할 때 해당 페이지의 js코드를 불러와야하는 비효율적인 페이지 이동이 발생한다.
그래서 프리페칭(Pre-fetching) 기능이 필요한 것이다.
이러한 방식을 통해 Next.js는 초기접속 요청 시에 하이드레이션을 더 빠르게 처리할 수 있도록 만들어주면서,
초기접속 이후 페이지 이동도 빠르게 처리할 수 있도록 작동하는 것이다.
✅ 실습으로 확인해보기
❗next앱을 개발모드("npm run dev")로 실행해놓고 있을 때는 프리페칭이 동작하지 않는다.
"npm run dev"로 앱을 실행시킨 후 개발자모드에서 Network탭을 확인해보면
해당 페이지로 이동할 때마다 필요한 js코드를 매번 서버로부터 받아오는 것을 확인할 수 있다.
index페이지로 초기접속 시 index페이지에 필요한 js파일만 불러오고 있다.
search페이지로 이동하면 search페이지에 필요한 js파일을 추가로 요청해서 불러온다.
그럼 프리페칭을 확인하기 위해 개발모드가 아닌 "npm run build"를 통해 앱을 빌드하고 "npm run start"로 빌드된 앱을 실행해보면,
index페이지로 초기접속 시에도 search페이지와 book페이지에 필요한 js파일을 프리페칭해온 것을 확인할 수 있다.
search페이지로 이동해도 network탭에는 추가적으로 아무 요청도 발생하지 않는다. book페이지도 마찬가지다.
(가끔 다시불러오는 경우 캐시가 만료되서 다시 불러오는 경우이고, 기본적인 동작은 프리페칭이 이루어진다.)
한 가지 예외상황을 살펴보자면, 위 화면에서 "/test 페이지로 이동" 버튼을 클릭 시 test페이지에 필요한 js파일을 추가로 불러온다.
코드를 보면 index, search, book의 경우 Link 컴포넌트로 구현했지만 test페이지로 이동하는 것은 함수로 작성했다는 것을 알 수 있다.
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 컴포넌트로 명시된 경로가 아니라면 프리페칭이 이루어지지 않는다.
만약 test페이지처럼 프로그래매틱하게 작성한 페이지의 이동도 프리페칭을 시키고 싶다면,
App 컴포넌트가 마운트되었을 때 router객체의 .prefetch() 메세드를 통해 프리페칭을 하도록 명시적으로 코드를 작성해주면 된다.
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 컴포넌트에 의해 자동으로 진행되는 프리페칭을 막는 방법도 있다.
<Link href={"/search"} prefetch={false}>search</Link>
프리페칭을 원하지 않는 페이지의 Link 컴포넌트의 prefetch라는 props를 false로 전달해주면 된다.
참고자료
'개발공부 > ⬛ Next.js' 카테고리의 다른 글
[Next.js] Global Layout과 페이지별 레이아웃 적용하기 (Using Pages Router) (0) | 2024.09.10 |
---|---|
[Next.js] 스타일링 (2) | 2024.09.07 |
[Next.js] 네비게이팅 (Navigating) (0) | 2024.09.04 |
[Next.js] Pages Router 방식으로 라우팅 설정하기 (0) | 2024.09.03 |
[Next.js] 사전 렌더링 이해하기 (0) | 2024.08.30 |
프론트엔드 개발자 삐롱히의 개발 & 공부 기록 블로그