Notice
Recent Posts
Recent Comments
Link
«   2025/03   »
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31
Tags more
Archives
Today
Total
관리 메뉴

개발의변화

Next Js 정리 1. 렌더링 전략 본문

프론트엔드

Next Js 정리 1. 렌더링 전략

refindmySapporo 2024. 4. 8. 15:33
반응형

SSR

하이드레이션(hydration)

서버 측에서 생성한 HTML페이지에 클라이언트 측에서 실행하는 자바스크립트 코드를 추가해서 애플리케이션을 관리하고 렌더링하는 기법

즉, 서버 측에서 생성한 HTML 페이지를 구성하는 각각의 DOM 객체에 필요한 자바스크립트를 추가해서 클라이언트단에서 동적으로 렌더링

장점: 웹 사이트 호환성, SEO(웹 크롤러 같은 검색 엔진 웹 문서 수집기가 페이지를 렌더링할 필요가 없음)

단점: 클라이언트가 요청할 떄마다 페이지를 다시 렌더링할 수 있는 서버가 필요 -> SSR 애플리케이션이 더 많은 자원을 소모하고 더 많은 부하를 보이며 유지보수 비용도 증가, 페이지에 대한 요청을 처리하는 시간이 길어짐

항상 주의해야 하는 점은 Next.js가 빌드 시점에 정적으로 페이지를 만든다는 점, 페이지에서 외부 AP를 호출하거나 데이터베이스에 접근하는 등 동적 작업을 해야 한다면 해당 함수를 페이지에서 익스포트해야함

getServerSideProps:

페이지에서 서버의 REST API를 호출하여 특정 사용자 정보를 가져온 다음 클라이언트에 전달해서 사용할 수 있도록 해야함

해당 함수를 export하는 페이지를 찾아서 서버가 페이지 요청을 처리할 때 실행됨

반드시 브라우저 전용 API를 사용해야 하는 컴포넌트가 있다면 해당 컴포넌트를 반드시 브라우저에서 렌더링하도록 명시적으로 지정해야 한다. (ex: window, document)

CSR

React index.html을 보면 body태그 안에 있는 <div id="root"> </div>밖에 없다는 것을 보여준다.

 

즉 root div 요소에 전체 애플리케이션을 렌더링 하는 것이다. 배포된 url에 접근하게 되면 HTML 마크업을 렌더링하고 빌드 과정에 주입한 script, link의 자바스크립트 번들고 css 파일을 다운로드하여 전체 애플리케이션을 렌더링 함

 

 

장점: 쉬운 페이지 전환, 지연 로딩과 성능, 서버 부하 감소
단점: 느린 초기 속도, 웹 앱의 SEO도 악영향

 

 

 


 

Next.js는 컴포넌트가 반환하는 HTML 마크업을 렌더링하고 스크립트를 페이지에 끼워 넣는다. 그리고 해당 컴포넌트가 브라우저에 마운트되면 라이브러리 함수를 클라이언트에서 호출하고 실행하도록 만든다. -> 라이브러리 함수를 호출하기 위에 useEffect와 useState를 활용해야 한다.

 

process.browser 변수

 

서버에서 렌더링할 때 브라우저 전용 API로 인한 문제를 다른 방법으로 해결할 수 있다.

process.browser 값에 따라 스크립트와 컴포넌트를 조건별로 실행하는 것

 

이 변수는 불린(boolean) 값으로, 코드를 클라이언트에서 실행하면 true, 서버에서 실행하면 false값을 가짐

const side:String = typeof window === "undefined" ? 'server' : 'client';

 

동적 컴포넌트 로딩

const Hightlight = dynamic(
() => import('../components/Hightlight'),
{ssr: false}
);

ssr:false옵션 -> 클라이언트에서만 코드를 실행한다고 명시

 

정적 사이트 생성(SSG)

 

일부 또는 전체 페이지를 빌드 시점에 미리 렌더링

웹 애플리케이션을 빌드할 때 내용이 거의 변하지 않는 페이지는 정적 페이지 형태로 만들어 제공

 

쉬운 확장: 정적 페이지는 단순한 HTML 파일이므로 CDN을 통해 파일을 제공하거나 캐시에 저장하기 쉬움

 

뛰어난 성능: 빌드 시점에 HTML 페이지를 미리 렌더링하기 떄문에 페이지를 요청해도 클라이언트나 서버가 무언가를 처리할 필요가 없음

 

안전한 API 요청: 페이지 렌더링을 위해 웹 서버가 민감하고 중요한 데이터를 클라이언트로 보낼 필요가 없음

 

-> 하지만 웹 페이지를 만들고 나면 다음 배포 전까지 내용이 변하지 않는다는 것

-> 정적 페이지를 다시 생성하는 과정을 반복해야 하는 문제가 생김

 

이를 해결하기 위해 Next.js는 증분 정적 재생성(ISR)을 활용

ISR: 어느 정도의 주기로 정적 페이지를 다시 렌더링하고 해당 내용을 업데이트할지 정할 수 있다.

 

 

실제로 SSG와 ISR을 합쳐서 활용한다면 서로의 단점을 해결할 수 있다.

 

예시로 엄청나게 많은 데이터를 가져와야 하는 대시보드를 만든다면 API 호출에 수 초가 소요되기에 데이터가 자주 변하지 않는다면 SSG와 ISR을 사용하여 데이터를 10분 동안 캐싱할 수 있다

import {GetStaticProps } from 'next';



interface DashProps {
user: String;
data: String
}

const dash = ({user,data}:DashProps) => {
 
return (
<div>
user = {user} , data = {data}
</div>
);
}

export const getStaticProps: GetStaticProps = async (ctx) => {
const userReq = await fetch('/api/user');
const userData = await userReq.json();

const dashboardReq = await fetch('/api/dashboard');
const dashboardData = await dashboardReq.json();



return {
props:{
user: userData,
data: dashboardData
},
revalidate: 600
}
}

export default dash

revalidate 옵션을 통해 10분마다 페이지에 대한 요청을 할 수 있다.

 

??근데 React-Query와 같은 data. fetching라이브러리로 API 캐싱처리를 해도 되는 거지 않나 ???

 

Reac-Query에 pre-fetching은 페이지가 렌더링되기 전에 미리 데이터를 가져올 수 있기에 Next.js에 성능 개선에 도움을 준다. ( 데이터 캐싱 작업도 pre-fetching에 포함된다)

 

반응형