예전 page router 방식을 사용하던 next.js에서 app router 방식을 도입한 이유를 알기 위해서는 기존 page router 방식을 제대로 이해하고 있어야 그 이유에 대해 납득할 수 있다는 생각에 정리겸 아직 사용해보지 못한 기술들에 대해 정리하고자 한다.
프로젝트 파일의 네이밍에서 여러 방법으로 동적 페이지, 정적 페이지를 구성할 수 있다.
[...id].tsx
는 경로상의 하위 인덱스 파일을 모두 인식하게 하는 방식이다. 즉, book/123/22/443 ...
이런식으로 라우팅해도 접속이 가능하다는 것이다. 여기서 useRouter 훅 내부의 값으로는 배열형태로 나타나게 되며, 여기서 404페이지가 나오게 되는 경우는 book/
일 경우다. 이러한 경우에는 따로 동일 파일 위치에서 index.tsx 파일을 만들어서 해결할 수 있다.
[[...id]].tsx 이 파일은 위에서 말한 catch all segment + 기본 index 페이지 위치를 합친 기능이다. 어떤 값이 들어오더라도 페이지 접속이 가능하다.
next.js에서는 사용자가 현재 페이지에서 다른 페이지로 이동할 가능성이 있는 페이지에 대해 미리 JS번들 파일들을 받아와서 페이지 이동을 빠르게할 수 있도록 해주는 기능이다.
이러한 기능을 사용하기 위해서는 Link
컴포넌트를 사용하여 페이지 이동을 하면 알아서 프리페칭 기능이 적용이 된다.
useRouter 훅을 사용하여 push를 할 경우에는 프리페칭 기능이 작동하지 않는다. 이는 추가적으로 코드를 작성해야 next.js에서 프리페칭 기능을 동작시킨다.
useEffect(() => {
router.prefetch("/test")
}, [])
그렇다면 여기서 궁금한 점이 생긴다. 이미 next.js에서는 처음 페이지 진입시 js번들 파일을 가져와서 추후 페이지 이동시에 서버에 데이터를 요청하지 않고 번들파일을 읽어 페이지를 바로 이동하는데, 왜 추가적으로 프리페칭을 통해서 데이터를 가져오는걸까?
그 이유는, /test
, /search
이러한 페이지 별로 js번들파일 안의 리액트 컴포넌트 코드를 각각 스플리팅하여 페이지별로 저장해두기 때문이다. 즉, 초기 페이지 진입시 JS번들 파일은 현재 페이지에 필요한 JS번들 파일만 전달이 되는 것이다.
이에 대한 순서를 정의한다면,
첫 페이지 진입 -> JS번들파일(첫 페이지만 서버에서 가져옴) -> 이동 가능성이 있는 페이지의 JS번들파일 pre-fetching(서버에서 가져옴) -> 첫 화면 렌더링 -> 페이지 이동시 가지고 있는 JS번들파일을 실행(client에서) -> 페이지 이동
이러한 동작을 production 환경에서 확인할 수 있다.
만약 Link컴포넌트의 프리페칭 기능을 사용하기 싫다면(사용자들이 자주 안 들어갈 것 같다면) prefetch={false}
로 해제할 수 있다.