NextJS pre-renders all pages

최정은·2023년 1월 14일
0

NextJS

목록 보기
2/3

기존 react의 문제점

페이지 소스 코드를 확인하면 출력한 데이터를 찾아 볼 수 없다.
즉, <div id=”root”> 태그만 존재한다.

여기에 대한 단점은

  1. 사용자들은 해당 데이터가 완전히 호출될 때 까지 페이지를 볼 수 없다.
  2. 검색 엔진 최적화. 빈 페이지(컨텐츠가 없는 페이지)를 검색 엔진에서 우선적으로 검색되지 않는다.

리액트에서는 화면이 렌더링 되고 난 후에 데이터 페칭이 시작된다.

그렇기 때문에 사용자가 처음 페이지를 방문했을때 서버가 클라이언트에게 재전송하는 페이지는 컨텐츠가 존재하지 않는 페이지를 보여주게 된다.

NextJS의 사전 렌더링 방식

기본적으로 NextJS는 동적 데이터가 없는 모든 페이지를 사전 렌더링 한다.

일단 특정 페이지로 이동하게 되면 NextJS는 사전 렌더링된 페이지를 반환한다.

사전에 HTML 페이지 완성, 콘텐츠를 다 채워서 사용자한테 넘겨준다.

또한 포함된 JS 코드를 다 보내준다. ⇒ hydrate 라고도 함.

사전 렌더링은 반드시 최초 로딩때만 실행된다. 첫번째 렌더링이 끝나면 이제 SPA로 바뀌면서 react가 모든 작업을 진행한다.

두 가지 방법이 있다고 합니다. 둘 중에 원하는걸 고르면 된다.

  1. Static Generation

    : 빌드되는 동안 모든 페이지가 사전 생성된다는 것.

  2. SSR

    : 빌드 후 서버에서 요청이 오는 그때 모든 페이지가 생성된다.

Static Generation

빌드 도중에 모든 페이지와 데이터가 사전 생성되는 것을 의미한다.

배포가 되고 나면 구축된 페이지는 서버나 앱을 실행시키는 CDN을 통해 캐시로 저장된다.

getStaticProps 함수를 이용해서 구현.

export async function getStaticProps(context) {...}

특징

  • 서버 사이드에서만 실행되는 모든 코드도 실행할 수 있다. (걍 쉽게 Node.js에서만 쓸 수 있는 코드를 사용할 수 있다.)

getStaticProps

모든 페이지 파일에 추가할 수 있고 페이지에서만 추가할 수 있고 export 해야한다.

이 함수는 이 페이지가 사전 렌더링이 되어야한다는 것을 NextJS에게 알린다.

또한 이 함수는 클라이언트 사이드에서 확인 할 수 없다. (Source 탭에 가서 보면 해당 함수가 없는 것을 확인할 수 있다.)

처음으로 index.js 파일에 컴포넌트와 함께 getStatisProps 함수를 생성한다.

// 두번째로 실행됨.
const HomePage = (props) => {
	return <></>
}

// 첫번째로 실행됨. 
export async function getStaticProps(){
	return {props: };
}
export default HomePage;

내부 동작

next build 명령어로 build가 시작되면 페이지를 사전 생성한다.(getStaticProps 이용시)

.next/server 에 들어가면 사전 생성 페이지를 볼 수 있다.

ISR(Incremental Static Generation)

페이지를 사전 생성 하긴 하지만 최대 X초마다 들어오는 모든 요청에 대해 주어진 페이지를 NextJS가 재생성 하도록 할 수 있다.

특정 시간에 따라 그 전엔 오래된 데이터가 있는 페이지를 제공하고

그 시간이 넘었으면 다시 서버에서 사전 생성 되어 가장 최신의 페이지를 제공한다.

export async function getStaticProps() {
	return {
		props: {
			products: data.products
		},
		revalidate: 600// 페이지 재생성까지 기다려야하는 시간(초 단위)
	}
}

기타 옵션

export async function getStatisProps(context){
	...	

	return {
		...
		notFound: bool,
		redirect:{
			destination: '/no=data'
		}
	}
}

이 context 매개변수는 NextJS로 실행될 때 페이지에 대한 추가 정보를 가졌다.

return 값에는 props, revalidate 말고도 두 가지 키 값을 지정해줄 수 있다.

  • notFound
    • true : 404 오류 반환, 404 오류 페이지가 나옴
    • 사용하는 이유?
      • fetch에 실패하면 발동
  • redirect
    • 다른 라우트로 리다이렉션
      • 이것 또한 데이터 fetch에 실패하면 발동하도록 처리할 수 있다.

getStaticPaths

next는 모든 페이지를 사전 렌더링을 하는데 ‘동적 페이지’는 예외로 삼는다.

Why?

동적 페이지는 하나의 페이지가 아니라 여러개의 페이지로 이루어지기 때문이다.

사전 생성 되는 페이지가 몇개나 필요한지 알 수 없음…

[pid]에서 어떤 값이 제공되는지를 모름 → 사전 생성 불가능.

이를 해결하기 위해서 getStaticPaths() 함수를 사용한다! (비동기 함수) (보통 getStaticProps 함수와 같이 사용한다.)

page 컴포넌트 파일에서만 사용할 수 있다.

동적 페이지의 어떤 인스턴스를 생성할지 NextJS에 알린다.

export async function getStaticPaths() {
  return {
    paths: [
      { params: { pid: 'p1' } },
      { params: { pid: 'p2' } },
      { params: { pid: 'p3' } }
    ],
    fallback: false
  };
}

fallback

: pre-render 되어야 할 페이지가 많은 때 도움이 된다. 필요한 경우에만 pre-render 되게 할 수 있다.

true로 값을 주게 되면 포함되지 않은 페이지라도 페이지 방문시 로딩되는 값이 유효할 수 있도록 NextJS에게 요청 가능.

단점 : 직접적으로 url에 접속하는 경우엔 값이 존재하지 않아 오류를 발생시킨다.

⇒ 해결방법 : 값이 존재하지 않을때 return 값으로 로딩 컴포넌트를 띄우거나 fallback: ‘blocking’ 문자열을 작성한다.

SSR(Server Side Rendering)

Static Generation이 빌드 중 페이지를 사전 생성한다면 SSR은 빌드 후 서버에서 요청이 오는 그때 모든 페이지가 생성된다.

getServerSideProps

페이지 요청이 서버에 도달할 때마다 실행되는 함수. (빌드 시간이나 매초마다 사전 생성 X)

서버쪽에서만 사전 렌더링이 된다.

export async function getServerSideProps(context) {
	const { params, req, res } = context;k
	...
}

context의 params에 접근할 수 있을 뿐만 아니라 요청(req), 응답(res) 객체에도 접근 할 수 있다.

req, res 객체를 이용하여 헤더나 쿠키의 값에 접근 할 수 있다.

위에 함수랑 가장 큰 차이점은 접근할 수 있는 데이터가 다르고, 함수가 실행되는 타이밍이 다르다는 점이다.

서버에서만 해당 코드가 실행되어 NextJS는 사전에 페이지를 생성할 필요가 없다. 그렇기 때문에 getStaticPaths 함수가 필요없게 되는것이다.

Client-side Data Fetching

NextJS로 개발을 하다보면 pre-render을 할 필요가 없거나 할 수 없는 경우가 생긴다.

  1. 갱신 주기가 잦은 데이터

    ex) 주식 페이지와 같이 실시간으로 차트가 변경되어 데이터가 자주 변경되는 경우

  2. 특정 유저에 한정되는 데이터

    ex) 쇼핑몰의 ‘내가 주문한 데이터’

  3. 데이터의 일부만 표시하는 경우

이럴때는 클라이언트 측에서 데이터 fetching 작업을 하는게 좋다!

0개의 댓글