Static Generation

Eunji Park·2022년 7월 20일
0

Next.js | 코딩앙마

목록 보기
11/13
post-thumbnail

✓ 분석하기

Next.js 는 모든 페이지를 기본적으로 Pre-Render 한다.

다시 말해, Client Side 의 JavaScript 가 모든 일을 하는 것이 아니라,
각 HTML 파일을 사전에 만들어 놓는다는 의미이다.

이렇게 Pre-Rendering 된 페이지들은 퍼포먼스 향상와 검색엔진최적화( SEO )에 더 좋다.

생성된 HTML 은 필요한 최소한의 JavaScript 코드만 존재하고,
브라우저에 의해 로드될 때 그 코드가 실행되어 완전한 페이지를 표한하게 되는 것이다.


JavaScript OFF 🚫

Pre-Rendering 을 하지 않았을 때 JavaScript 를 껐을 때, 화면에 아무것도 나타나지 않을 것이다.

🔗 Chrome 개발자 도구 / JavaScript 끄기


아래의 결과 화면을 확인해보자.

▶ Home

JavaScript 가 꺼진 상태이기 때문에 CSS 가 적용되지 않고 API 호출이 막힌 상태이지만,
페이지 소스를 확인하면 head 태그 안에 설정한 title 과 meta 태그 정보가 설정한대로 잘 나타난다.
사용자가 빠르게 이 페이지로 들어올 수 있고, SEO 도 문제없이 잘 처리된다.


▶ About

About 페이지도 CSS 가 적용되지 않을 뿐,
페이지 소스를 확인하면 head 태그 안에 설정한 title 이 올바르게 나타난다.


▶ View ( 상세페이지 )

View 는 Server-Side Rendering 으로 구현되었다.
즉, 서버에서 데이터를 가져와서 HTML 로 만든 다음 내려준다는 의미이다.
그렇기 때문에 제품에 대한 이미지와 정보가 화면에 나타난다.

이 페이지에서 JavaScript 가 하는 역할은 CSS 를 가져오고 onClick 함수 등 최소한으로 구현되어 있다.
하지만 JavaScript 는 꺼진 상태이기 때문에 앞서 언급한 기능들만 작동하지 않는다.

💡 이 페이지에서 Next.js 의 장점을 확인할 수 있다...!!
SPA 환경에서 이렇게 SSR 으로 구현하면 Multi Page Application 못지않게
검색 엔진 최적화( SEO )에 대응하고, 퍼포먼스도 향상시킬 수 있다.




✓ 사전 렌더링 ( Pre-Rendering )

비교하기

❌ No Pre-Rendering

Pre-Rendering 을 하지 않으면
초기에는 아무것도 나타나지 않고, JS 가 로드된 이후에 페이지가 채워진다.

⭕ Pre-Rendering

Pre-Rendering 를 하면
초기에 사전에 만들어진 HTML 요소들( meta 데이터 포함 )이 화면에 그려진다.
그 다음 JS 가 로드되면 <Link /> 같은 컴포넌트들이 작동하게 된다.
이를 Hydration ( 정적인 무언가에 동적인 요소들을 입혀 생기를 불어 넣는 작업 ) 이라고 부른다.
다시 말해, 정적인 HTML 에 JS 를 입혀 동적으로 만들어 내는 것을 의미한다.

Pre-Rendering 2가지 방법 ⭐

사전 렌더링 ( Pre-Rendering ) 은 2가지 방식으로 적용된다.
이 두 방법의 차이점은 "언제 HTML을 만드는가?"이다.

1. 정적 생성 ( Static Generation )

Static Generation 은 빌드 시에 HTML 을 생성한다.
미리 만들어 놓은 HTML 을 Client 에서 요청할 때마다 재사용해서 주는 것이다.

그렇다면 정적 생성( Static Generation ) 방식은 언제 사용하면 좋을까?
페이지를 빌드 시점에 만들어두고, CDN 을 통해 재사용하기 때문에 대부분의 경우 정적 생성 방식이 훨씬 빠르고 좋다.

정적 생성( Static Generation ) 방식은
사용자가 요청하기 전에 페이지를 미리 만들어 놓아도 되는 경우 사용한다.


Next.js 에서는 다음과 같은 경우에 정적 생성 방식을 권장하고 있다.

  • 마케팅 페이지
  • 블로그 게시물
  • 제품 목록
  • 도움말, 문서


2. 서버 사이드 렌더링 ( SSR, Server-Side Rendering )

Client 에서 요청하면 그때 HTML 을 만들어서 보여준다.

⭐ SSR( Server-Side Rendering ) 방식은 다음과 같은 경우에 사용한다.

  • 항상 최신 상태를 유지
  • 관리자 페이지
  • 분석 차트


Next.js 는 페이지별로 정적 생성 vs SSR 렌더링 방식을 개발자가 선택해서 구현할 수 있다.




✓ 직접 해보기

SSR 방식

SSR ( Server-Side Rendering ) 방식은 제품 상세 페이지를 구현할 때 적용했던 방식이다.
다시 한번 살펴보자.

▶ getServerSideProps

📁 / pages / view / [id].js


Static Generation 방식

▶ 외부에서 데이터를 가져오지 않는 정적 생성 방식

📁 / pages / about.js

about 페이지의 경우에는 어떤 데이터도 필요없는 페이지로, 정적 생성 방식으로 구현되었다.


▶ 외부에서 데이터를 가져오는 정적 생성 방식

(1) getStaticProps

Next.js 에서 제품 목록 페이지는 정적 생성 방식을 권고하였으므로
외부 데이터를 받아오는 제품 목록 페이지에 정적 생성 방식을 적용시켜보자.

📁 / pages / index.js

Axios 로 데이터를 불러오는 getStaticProps 영역은 Client 영역이 아니기 때문에
환경 변수에 NEXT_PUBLIC_ 을 붙일 필요가 없다.
따라서 환경 변수 파일에 apiUrl 변수를 추가로 생성한다.

📁 / .env.development

📁 / .env.production


결과 화면 ( development mode )

npm run dev 명령으로 development mode 에서 결과를 확인해보자.

빈 화면을 그린 다음 API 호출을 통해서 데이터를 받아온 후 빈 화면을 채우는 것이 아니라,
미리 만들어진 Static HTML 을 제공한 것이다.

home 페이지로 이동하면 빈 화면 없이 제품 목록이 나타난다.

페이지 소스를 보면 모든 데이터가 잘 채워져 있는 것을 확인할 수 있다.


결과 화면 ( production mode )

.next 폴더를 삭제한 후, npm run build 한다.
그 결과 .next 폴더가 다시 생기고 그 안에 필요한 파일들이 들어가게 된다.

📁 / .next / pages 안의 파일들을 살펴보면
Server 에서 사용되는 static 한 파일들이 만들어져 있는데 HTML 로 만들어져 있는 것을 확인할 수 있다.
이렇게 만들어진 HTML 파일을 재사용하는 것이다.

그 다음 ``npm run start``` 명령으로 production mode 에서 결과를 확인해보자.

개발자 도구의 Network 탭을 살펴보자.
용량은 22.8KB 로 처음 로드하는데 약 1s 정도 걸렸다.
다시 새로고침 하면 이미 만들어진 HTML 을 보여주는 방식이기 때문에 약 3ms 만에 로드되는 것을 확인할 수 있다.


(2) getStaticPaths

Dynamic Router 는 정적 생성이 불가능한 것일까?

이 예시의 경우,
Dynamic Router 는 어떤 아이디가 들어올지 모르기 때문에 모든 제품에 대한 HTML을 생성하는 것은 불가능하다.

단, 개수가 한정적이고 들어올 아이디 번호를 미리 알 수 있으면 가능하다.
이 경우에 getStaticPaths를 사용한다.

모든 제품에 대해 대응할 수 없으니, 가장 상단에 있는 3개의 제품에 대해서만 대응해보자.
( 740번 , 730 번 , 729 번 )


view 폴더를 복사하고, 복사한 폴더명을 detail 로 수정한다.
이 detail 폴더에 getStaticPaths를 활용하여
740 번, 730 번, 729 번 제품의 Dynamic Router 에 정적 생성 방식을 적용해보자.


📁 / .src / component / ItemList.js
제품을 클릭했을 때 view 폴더가 아니라 detail 폴더로 이동해야 하므로 주소를 알맞게 수정한다.


📁 / pages / detail / [id].js


결과 화면 ( production mode )

.next 폴더를 삭제한 후, npm run build 한다.
그 결과 .next 폴더가 다시 생기고 그 안에 필요한 파일들이 들어가게 된다.
그 다음 npm run start 명령으로 production mode 에서 결과를 확인해보자.

그 결과 home 과 제품 목록의 가장 상단에 있는 3개의 제품( 740번 , 730 번 , 729 번 )에 대한 상세페이지는
빠르게 로드 되는 것을 확인할 수 있다.

HOME ( 제품 목록 )

제품 상세페이지 ( 740번 , 730 번 , 729 번 )


제품 상세페이지 ( 그 외 )
740번 , 730 번 , 729 번을 제외한 다른 제품들을 클릭하면 404 페이지가 뜬다.


이 현상은 fallbackfalse 로 설정했기 때문에 나타난다.


이제 fallbackture 로 설정하고 그 결과를 확인하자.

처음에는 첫 번째 이미지처럼 제품 정보가 없는 상태의 페이지를 보였다가,
시간이 조금 지나고 두 번째 이미지처럼 제품 정보가 채워진 화면이 나타난다.

fallback

  • false  :  없는 페에지 대응을 하지 않는다. 그냥 404 에러가 나타나게 된다.
  • ture  :  getStaticPaths 로 전달된 경로들이 빌드 타임에 만들어지는 것은 변함없다.
                다만, 나머지들은 최초 접속 시에 Props 가 빈 상태로 그려지고
                이후에 background에서 정적 파일로 HTML 과 JS를 생성해준다.
                그 다음에 Next.js 는 Pre-Rendering 목록에 추가한다.
                두 번째 로드부터는 정적 생성된 페이지를 사용하기 때문에 새로고침 해도
                데이터가 비어있는 상태의 페이지는 보이지 않게 된다.

0개의 댓글