export default function Home() {
return "hi"
}
next.js의 pages 폴더 안의 index 파일을 만들고 위와 같은 코드를 입력했을 때 자동적으로 웹사이트에서 바로 보이게 됩니다.
이는 framework와 library의 결정적인 차이점을 보여주는데 바로 next.js에서의 index.js 파일은 일반적으로 페이지의 진입점을 나타내는 파일이라는 점입니다.
이것은 즉 next.js는 파일 기반의 라우팅을 사용하여 페이지를 관리한다는 의미입니다.
디렉토리 내부의 파일들이 각각의 경로와 매핑됩니다. 따라서 index.js 파일은 웹 어플리케이션의 루트("/")에 해당하는 페이지를 정의하는 파일입니다.
반면에, react 프로젝트 생성시에는 어떤 폴더 구조를 만들지 스스로 정할 수 있습니다. 그렇기 때문에 상대적으로 next.js로 앱을 만들때보다 자유롭습니다.
그래서 Routing 또한 home이나 about이나 등등 다른 어떤 페이지로 어떻게 넘어가게 할지는 다 스스로한테 달려있습니다.
하지만 React Router Dom을 다운받고 그 다음 관련 설정을 마치고, router을 만들고 routes를 설계하고 component를 import 해야하는 등 next.js보다 좀 더 복잡한 과정에 의해 페이지관리를 해야합니다.
next.js의 좋은 기능 중 하나는 앱에 있는 페이지들이 미리 렌더링(pre-rendering) 된다는 점 입니다. 즉 정적으로 생성되는 것인데요.
create react-app과 비교하여 설명해보겠습니다. react app은 next.js와 다르게 client-side render 입니다.
client side-render란?
브라우저가 ui를 만드는 모든 것을 한다는 의미입니다.
이말인 즉 react.js를 통해서 화면에 보이는 대부분의 것들은<div id="root"></div>위 root 요소를 제외하고는 모두 javascript입니다. 유저가 보게 될 html은 root 요소가 전부이고 브라우저는 html파일을 받아오고, 이후에 javascript 파일을 다운로드 합니다. javascript파일이 로딩되고 실행된 후, 앱이 초기화 되고 UI가 생성됩니다.
그렇기 때문에 CRA(Create React App)는 초기 로딩 시간이 길어질 수 있다는 단점이 있습니다.
반면에 위에서 잠깐 말했듯이 next.js는 server side-render를 지원하기 때문에 앱의 페이지들은 서버에서 미리 렌더링(pre-rendering)되고 정적으로 생성됩니다. 즉 사용자가 페이지에 접속했을 때 미리 만들어진 html이 전달됩니다. 이로 인해서 초기 로딩 시간이 단축되고, 사용자는 페이지를 더 빨리 볼 수 있습니다. 또한 검색 엔진 최적화(SEO)에도 유리합니다.
이해가 잘 되지 않는다면, Create React App을 실행한 뒤 chrome 설정에서 javascript를 비활성화 해보면
<noscript>you need to enable Javascript to run this app</noscript>
화면에서 위의 내용이 확인되는 것을 볼 수 있습니다.
또한 next.js에서 useState를 통해서 다음과 같은 Counter 기능을 추가하고 페이지를 로딩한다고 가정했을 때
import { useState } from "react";
export default function Home() {
const [counter, setCounter] = useState(0);
return (
<div>
<h1>hello {counter}</h1>
<button onClick={() => setCounter((prev) => prev + 1)}>+</button>
</div>
);
}
미리 렌더링(pre-rendering)으로 인해 생성된 html document가 클라이언트에게 전송되어 웹화면의 ui를 볼 수 있습니다. 그런데 우리가 보게 되는 화면은 웹화면만 보여주는 html일 뿐이고 javascript 요소들이 하나도 없는 상태입니다. 이는 웹 화면을 보여주고는 있지만 특정 js module 뿐만 아니라 단순 클릭과 eventListener이 각 웹페이지의 DOM 요소들이 적용되어 있지 않은 상태임을 말합니다.
그러면 이와 같은 웹페이지가 이후에 어떻게 정상적으로 동작하는냐인데 next.js server에서 페이지 로딩 시 미리 렌더링(pre-rendering)을 통해 웹페이지를 클라이언트에게 보내고 나서 바로 react.js가 번들링된 javascript 코드를 클라이언트에게 전송합니다.
그리고 이 과정을 hydrate라고 부릅니다.
하지만 sever에서 한번 렌더링이 되고, client에서도 한 번 더 렌더링이 되어서 오히려 SSR이 더 비효율적인 렌더링 방식이 아닌가 할 수 있지만 server에서 미리 렌더링(pre-rendering)을 통해서 유저에게 빠르게 웹페이지로 응답할 수 있다는 점과 모든 javascript 요소들이 빠진 굉장히 가벼운 상태의 document를 미리 렌더링(pre-rendering)한 후 클라이언트 단에서 각 DOM요소에 javascript 속성을 매칭할 시에 실제 웹페이지를 다시 그리는 과정까지는 가지 않기 때문에 브라우저에서 두번 렌더링되는 CCR의 단점을 보완한 좀 더 효율적인 방식의 렌더링이라고 할 수 있습니다.
1. 파일 시스템 기반의 라우팅
2. 클라이언트 사이드 렌더링(CSR)과 서버 사이드 렌더링(SSR)