넥스트는 어떤 페이지를 빌드 시점에 정적으로 생성하고 어떤 페이지를 실행 시점에 동적으로 제공할 것인지 쉽게 정할 수 있다
2.1 서버 사이드 렌더링(SSR)
서버 사이드 렌더링은 PHP처럼 HTML 페이지를 웹 브라우저로 전송하기 전에 서버에서 전부 렌더링 함. 그리고 해당 페이지의 모든 자바스크립트 코드가 적재되면 동적으로 페이지 내용을 렌더링함.
Next도 용청에 따라 서버에서 HTML 페이지를 동적으로 렌더링하고 웹 브라우저로 전송할 수 있음. 서버에서 렌더링 한 페이지에 스크립트 코드를 집어넣어서 나중에 웹 페이지를 동적으로 처리할 수도 있는데 이를 하이드레이션이라고 함
더 안전한 웹 애플리케이션
페이지를 서버에서 렌더링 한다는 것은 쿠키 관리, 주요 API, 데이터 검증 등과 같은 작업을 서버에서 처리한다는 뜻, 중요한 데이터를 클라이언트에 노출할 필요가 없어서 안전함
더 뛰어난 웹 사이트 호환성
클라이언트 환경이 자바스크립트를 사용하지 못하거나 오래된 브라우저를 사용하더라도 웹 페이지드를 제공할 수 있음
Next.js는 기본적으로 빌드 시점에 정적으로 페이지를 만듦. 그래서 외부 API를 호출하거나 데이터베이스에 접근하는 등 동적 작업을 해야 한다면 해당 함수를 페이지에서 익스포트 해야 함
아래 사진은 프롭으로 가져온 데이터를 받고 있음
Next.js는 getServerSideProps 예약 함수를 사용해야 함. 페이지에 대한 요청이 들어오면 서버가 REST API를 호출해서 필요한 사용자 정보를 가져옴.
- getServerSideProps라는 비동기 함수를 익스포트함. 빌드 과정에서 Nest.js는 이 함수를 익스포트 하는 모든 페이지를 찾아서 버서가 페이지 요청을 처리할 때 getServerSideProps 함수를 호출하도록 만듦. 해당 함수 내의 코드는 항상 서버에서만 실행됨
- getServerSIdeProps 함수는 props라는 속성값을 갖는 객체를 반환함. Next.js는 이 props를 컴포넌트로 전달하여 서버와 클라이언트 모두가 props에 접근하고 사용할 수 있음. fetch API는 Next.js를 통해 서버에서 실행되기 때문에 fetch API를 변도의 폴리폴로 끼워 넣을 필요는 없음.
- IndexPage 함수를 수정해서 props를 인자로 받음. 이 props는 getServerSideProps 함수에서 반환한 props의 모든 내용을 가지고 있음.
이제 코드를 배포하고 실행하면 Next.js는 외부 API를 호출해서 필요한 데이터를 가져온 다음 IndexPage를 서버에서 동적으로 렌더링 함. 그럼 사용자별로 서로 다른 페이지를 볼 수 있음.
SSR은 이점이 많지만 주의해야 할 점도 있음. 브라우저 전용 API를 사용해야 하는 컴포넌트가 있다면 해당 컴포넌트를 반드시 브라우저에서 렌더링 하도록 명시적으로 지정해야 함. Next.js는 페이지를 기본적으로 서버에서 렌더링 하기 때문에 window, document와 같은 객체나 API를 제공하지 않음. 이런 부분에서 CSR필요
2.2 클라이언트 사이드 렌더링(CSR)
리액트로 개발을 해봤다면 기본적으로 아래 사진과 같은 index.html만 있는 것을 볼 것이다
네이티브 애플리케이션처럼 느껴지는 웹 애플리케이션
자바스크립트 번들을 다운로드한다는 것은 웹 애플리케이션이 렌더링 할 모든 페이지가 이미 브라우저에 다운로드되어 있다는 뜻. 다른 페이지로 이동하면 새로고침을 하지 않고 새로운 페이지를 다운로드하지 않고 페이지가 이동됨.
쉬운 페이지 전환
새로고침을 할 필요 없이 페이지 전환가능
지연된 로딩과 선능
최소한의 HTML 마크업만 렌더링 하면 됨
서버 부하 감소
서버는 아주 간단한 HTML만 넘겨주면 되어서 강력한 서버가 필요 없음
하지만 단점들이 있는데 JS, CSS 파일을 다운을 다 받을 때까지 기다려야 하는데 이때 빈 화면의 페이지가 보임. 그러면 SEO에 영향을 줌
Next.js는 기본적으로 특정 페이지 내의 모든 리액트 컴포넌트를 서버에서 렌더링 하거나 비드 시점에 미리 렌더링함.
React.useEffect
Next.js에서는 특정한 컴포넌트는 클라이언트에서 렌더링 되게 할 수 있음
아래 사진처럼 useEffect와 useState를 이용하여 할 수 있음 그럼 브라우저에서만 렌더링 됨 (아래 사진에서 <Highligh> 컴포난토는 브라우저에서만 렌더링이 됨
동적 컴포넌트 로딩
아래 사진은 dynamic로 동적으로 컴포넌트를 가져옴 옵션으로 클라이언트에서 렌더링 하는 것으로 해주면 useEffect와 useState를 사용한 것과 똑같이 됨
2.3 정적 사이트 생성(SSG)
SSG는 일부 또는 전체 페이지를 빌드 시점에 미리 렌더링함
쉬운 확장
정적 페이지는 단순 HTML 파일이므로 CDN을 통해 파일을 제공하거나 캐시에 저장하기 쉬움
뛰어난 성능
빌드 시점에 HTML 페이지를 미리 렌더링 하기 때문에 페이지를 요청해도 클라이언트나 서버가 무언가를 처리할 필요가 없음.
더 안전한 API 요청
페이지 렌더링을 위해 웹 서버가 민감하고 중요한 데이터를 클라이언트로 보낼 필요가 없음. 필요한 모든 정보가 빌드 시점에 미리 페이지로 렌더링이 되어 있기 때문
아쉬운 점
일단 웹 페이지를 만들고 나면 다음 배포 전까지 내용이 변하지 않음. 예를 들어 블로그에 새로운 글을 올렸는데 제목에 오타가 있는 경우를 생각하면. 제목 하나 고치기 위해 글을 불러오고 정적 페이지를 다시 생성하는 과정을 반복해야 함. 정적으로 생성한 페이지는 빌드 시점에 미리 렌더링 되어 정적 자원처럼 제공되기 때문.
이 문제를 해결하기 위한 게 증분 정적 재생성(ISR) 임. 얘는 주기를 가지고 정적 페이지를 다시 렌더링 하고 해당 내용을 업데이트할지 정할 수 있음.
예를 들어 동적 콘텐츠를 제공하지만 해당 콘첸츠 데이터를 가져오는데 아주 오랜 시간이 걸리는 웹 페이지를 떠올려보면. 이 페이지를 SSR 또는 CSR 형태로 제공하면 사용자는 이 데이터를 보기 위해 오래 기다려야 함. 이때 SSR과 ISR를 함께 사용하면 됨.
아래 코드는 그 방식을 적용한 거임 getStaticProps로 데이터를 가져오는데 대신 옵션으로 revalidate를 줘서 해당 시간마다 다시 재생성하라는 걸 명시해 줌
과정
- 빌드 과정에서 페이지의 내용을 getStaticProps 함수가 반환한 객체의 값으로 채움 그리고 이 페이지는 빌드를 거쳐 정적 페이지로 만들어버림
- 처음 10분간 해당 페이지를 요청하는 모든 사용자는 동일한 정적 페이지를 제공받음.
- 10분이 지나고 해당 페이지에 대한 새로운 요청이 들어오면 Next.js는 이 페이지를 서버에서 다시 렌더링 하고 getStaticProps 함수를 다시 호출. 그리고 렌더링 한 페이지를 저장해서 새로운 정적 페이지로 만들고 이전에 만든 정적 페이지를 새로 만든 페이지로 덮음.
- 이후 10분간 동일한 페이지에 대한 모든 요청에 대해 새로 만든 정적 페이지 제공
실무에서 바로 쓰는 NextJS책을 보고 중요한 부분 요약
문제시 삭제 하겠습니다.
'프론트엔드 > NextJS' 카테고리의 다른 글
[NextJS] e2e - PlayWright 설치 및 메인화면 띄우기(1) (1) | 2024.02.06 |
---|---|
Page Caching [Full Route Cache, Router Cache ] (1) | 2024.01.29 |
나도 오픈소스 기여를 ?!?! (with react-query) (0) | 2023.07.15 |
Server mutate시 react-query cache 사라짐 현상 (0) | 2023.07.15 |
서버 컴포넌트로 데이터 불러오기 (0) | 2023.04.25 |