본문으로 바로가기

 

 

Next.js는 서버 사이드 렌더링을 수행하지만 동시에 싱글 페이지 애플리케이션과 같이 클라이언트 라우팅 또한 수행합니다. 이러한 방식의 라우팅이 다소 생소하게 느껴질 수 있으며, Next.js를 처음 접했을 때 가장 혼란을 느끼는 부분입니다. 서버 사이드 렌더링과 클라이언트 라우팅이 혼재돼 있는 것이 복잡하게 느껴질 수도 있습니다.

 

아래 코드를 살펴보겠습니다.

import type { NextPage } from 'next';
import Link from 'next/link';

const Home: NextPage = () => {
  return (
    <ul>
      <li>
        <a href="/dashboard">
          A 태그로 이동
          </a>
      </li>
      <li>
        {/* 차이를 극적으로 보여주기 위해 리소스 미리 가져오는 prefetch off */}
        <Link prefetch={false} href="/dashboard">
          next/link로 이동
        </Link>
      </li>
    </ul>
  )
}

export default Home;

 

next/link는 Next.js에서 제공하는 라우팅 컴포넌트이며, <a /> 태그와 비슷한 동작을 합니다. 그러나 자세히 살펴보면 한 가지 큰 차이점이 보입니다. 아래 화면을 보시면 이해가 될 것입니다. 먼저 <a /> 태그로 이동해 보았습니다. 

<a> 태그로 페이지를 이동했을 때의 네트워크 탭에 표시되는 결과, 모든 리소스를 처음부터 다시 받는 것을 볼 수 있습니다.

 

이번에는 <Link> 태그로 이동한 결과를 살펴보겠습니다.

<Link> 페이지를 이동했을 때의 네트워크 탭에 표시되는 결과. 모든 리소스를 받는 것이 아니라 dashboard 페이지 이동에 필요한 내용만 받는 것을 알 수 있습니다.

 

전자와 후자를 반복해서 클릭하다 보면 전자는 잠시 깜빡인 이후에 페이지 라우팅을 하지만 후자는 매우 매끄럽게 마치 싱글 페이지 애플리케이션처럼 페이지 전환인 일어나고 있음을 알 수 있습니다. 둘 다 페이지를 이동하는 것은 동일한데, 어떠한 차이가 있을까요?

 

먼저 전자의 예제, 즉 <a>로 이동하는 경우를 살펴봅시다. 네트워크에는 dashboard라는 이름의 문서를 요청하고 있으며, 이후에는 webpack, framework, main, dashboard 등 페이지를 만드는 데 필요한 모든 리소스를 처음부터 다 가져오는 것을 알 수 있습니다. 이것은 서버에서 렌더링을 수행하고, 클라이언트에서 hydrate 하는 과정에서 한 번 더 실행됐다는 것을 알 수 있습니다.

 

이번에는 <Link> 태그를 살펴보면, 네트워크에 dashboard만 존재하며, 나머지 어떠한 요청도 없는 것을 볼 수 있습니다. next/link로 이동하는 경우 서버 사이드 렌더링이 아닌, 클라이언트에서 필요한 자바스크립트만 불러온 뒤 라우팅하는 클라이언트 라우팅/렌더링 방식으로 작동하는 것을 확인할 수 있습니다. Next.js는 서버 사이드 렌더링의 장점, 즉 사용자가 빠르게 볼 수 있는 최초 페이지를 제공한다는 점과 싱글 페이지 애플리케이션의 장점인 자연스러운 라우팅이라는 두 가지 장점을 모두 살리기 위해 이러한 방식으로 작동한다는 것을 기억해 둡시다.

 

따라서 이러한 Next.js의 장점을 적극 살리기 위해서는 내부 페이지 이동 시 다음과 같은 규칙을 지켜야 합니다.

  • <a> 대신 <Link>를 사용합니다.
  • window.location.push 대신 router.push를 사용합니다.

 

애플리케이션을 처음부터 서버에서 다시 불러와야 하는 정말~ 드문 케이스 외에는 Next.js가 제공하는 라우터를 사용해 페이지를 이동하는 것이 좋습니다.

 

 

 

References

[Next.js] 페이지 구조

React Deep Dive