728x90
반응형
프리렌더링(Pre-randering)
웹페이지 로딩 이전에 하는 렌더링
렌더링 과정
- 서버에서 HTML과 JavaScript 불러오기: 이 단계에서 Next.js는 페이지의 초기 버전을 빌드합니다. 이 초기 버전은 서버에서 생성된 정적 HTML로 구성되며, 클라이언트 측 JavaScript 번들도 포함합니다. 이 과정은 페이지가 빠르게 로드되도록 하며, 검색 엔진 최적화(SEO)에도 유리합니다.
- 리액트 실행: 사용자의 브라우저가 초기 HTML을 받은 후, 클라이언트 측 JavaScript가 실행되어 리액트를 시작합니다. 이 단계에서 리액트는 서버에서 받은 HTML과 동기화를 시도하며, 필요한 경우 추가적인 데이터를 가져오거나 사용자 인터랙션에 대응합니다.
- 클라이언트 사이드 렌더링에서 리액트가 화면 조정 (Hydration): 이 단계는 'hydration'이라고 불리며, 이때 리액트는 서버에서 렌더링된 HTML에 이벤트 핸들러 같은 동적 기능을 연결합니다. 이 과정을 통해 페이지는 완전한 리액트 애플리케이션으로 변모하며, 사용자와의 상호작용이 가능해집니다.(이미 랜더링된 html 와 리액트의 데이터를 연결하는 작업을 hydration이라고 한다)
그리고 프리렌더링은 이 과정 그러니깐 서버에서 데이터를 받아오기 전에 일어난다
이러한 과정을 통해 Next.js는 서버 사이드 렌더링(SSR)의 이점과 클라이언트 사이드 렌더링(CSR)의 동적 기능을 모두 활용할 수 있고 이 방식은 초기 페이지 로드 시간을 단축하고 사용자 경험을 향상시키는 데 도움이 됨
프리렌더링의 2가지 방법
정적 생성 (Static Generation) |
서버 사이드 렌더링 (Server Side Randering(SSR)) |
|
정의 | 정적 생성은 빌드 시간(build time)에 HTML 파일을 생성하는 방법 |
각 요청에 대해 서버가 HTML을 실시간으로 생성하는 방법 |
장점 | 페이지 로딩이 매우 빠름. 서버가 요청마다 HTML을 생성할 필요가 없기 때문에 서버 부하가 줄어들고 성능이 향상. |
항상 최신 상태의 데이터를 제공할 수 있음. 사용자의 요청에 따라 동적으로 페이지를 생성할 수 있어 자주 변경되거나 사용자별 커스터마이즈가 필요한 페이지에 적합. |
적용한 페이지 예시 | 블로그 게시물, 문서 페이지, 제품 목록 | 사용자 프로필, 실시간 정보가 필요한 대시보드, 사용자 인터랙션이 많은 애플리케이션 등 |
next.js에서는 코드를 작성하고 실행하면 우리도 모르게 정적 생성을 해준다.
※ 정적 생성(getStaticPaths( ), getStaticProps( ))함수와 서버 사이드 렌더링(getServerSideProps( ))함수는 같이 사용 할 수 없음
데이터 참고자료
https://jsonplaceholder.typicode.com/
● 정적 생성 코드(getStaticPaths( ), getStaticProps( ))
pages/index.js
import { ThemeContext } from "@/context/ThemeContext";
import Image from "next/image";
import Link from "next/link";
import { useRouter } from "next/router";
import { useContext, useState } from "react";
// 정적 생성
export async function getStaticProps(context) {
const res = await fetch("https://jsonplaceholder.typicode.com/posts");
const result = await res.json();
const users = result ?? [];
return { //리턴으로 반환해주는 값는 아래와 같은 객체형태여야한다(아니면 에러뜸)
props: {
users,
},
};
}
.....
return (
<>
....
<h2>리스트</h2> ////// 가져온 데이터
{users.map((user) => {
return (
<Link key={user.id} href={`/next/${user.id}`}>
<div
style={{
border: "1px solid #fff",
marginBottom: "10px",
width: "500px",
}}
>
<h3>
{user.id}.{user.title}
</h3>
</div>
</Link>
);
})}
</>
);
}
▶ 다이나믹 라우팅 사용해서 정적생성
pages/prev/[id].js
import Link from "next/link";
// getStaticProps(context)에서 해당 id값이 필요하기 때문데
// getStaticPaths()함수에서 데이터 id 값들을 매핑해서 params 에 등록해준다
export async function getStaticPaths() {
const res = await fetch("https://jsonplaceholder.typicode.com/posts/");
const result = (await res.json()) ?? [];
const paths = result.map((path) => ({
params: { id: String(path.id) },
}));
return {
paths,
fallback: true, // 아래 내용 참고
};
}
//
export async function getStaticProps(context) {
const userId = context.params["id"]; //아래 내용 참고
let user;
try {
const res = await fetch(
`https://jsonplaceholder.typicode.com/posts/${userId}`
);
user = await res.json();
if (!user || Object.keys(user).length === 0) {
throw new Error("에러");
}
} catch {
return {
notFound: true, // 값이 없으면 404 페이지로 넘어감
};
}
return {
props: {
user,
},
};
}
export default function next({ user }) {
if (!user || Object.keys(user).length === 0) {
//데이터의 값이 없을 때 빈 객체를 넘겨줘서 이런 조건을 줬음
return <div>로딩중입니다.</div>; // 404 페이지 넘어가기전에 로딩 걸림
}
return (
<div>
<h3>제목</h3>
<h3>{user.title}</h3>
<h3>내용</h3>
<p>{user.body}</p>
<Link href={"/"}>뒤로가기</Link>
</div>
);
}
1. fallback: 정적으로 생성되지 않은 경로에 대한 처리 방식을 설정( 3가지 값이 있음 )
false | - 반환된 경로들만 정적으로 생성. - 미리 생성되지 않은 경로에 접근하면, 404 페이지가 표시. - 필요한 모든 경로가 빌드 시점에 알려져 있고 추가적인 경로가 필요 없는 경우에 적합 |
true | - 반환되지 않은 경로에 대한 페이지 요청 시 사용자에게 먼저 빈 페이지가 보여짐. - 페이지가 생성되면, Next.js는 빈 페이지를 완전한 페이지로 교체함 - 이 방법은 필요한 경로가 많거나, 사용자가 접근할 수 있는 경로가 빌드 시점에 알려져 있지 않을 때 유용 - 첫 번째 사용자는 페이지가 생성되는 동안 대기해야 하지만 이후에는 누구나 생성된 페이지를 볼 수 있음. |
blocking | - true 와 비슷하게 작동하지만 사용자가 빈 페이지를 보는 대신 페이지가 서버에서 완전히 생성될 때까지 대기함 - 생성된 페이지는 클라이언트에 직접 전달되므로 사용자는 빈 페이지를 볼 필요가 없 - 사용자에게 빈 페이지를 보여주지 않으면서도 필요에 따라 페이지를 동적으로 생성하고 싶을 때 적합 |
2. context 속성 : 페이지 생성을 위한 추가적인 데이터나 파라미터를 제공하기 위해 사용
params | 동적 라우팅을 사용하는 페이지의 경우 현재 페이지에 대한 경로 매개변수(route parameters)를 포함 ex) [id].js 각 데이터를 매핑해서 id값을 추출해서 params에 등록해준다 (params: { id: 값 }) |
preview | 페이지가 프리뷰 모드(preview mode)에서 렌더링되고 있는지 여부 |
previewData | 프리뷰 모드에서 사용되는 데이터. setPreviewData 함수를 통해 설정된 데이터가 이 속성을 통해 전달 |
locale | 페이지에 설정된 현재 로캘(locale)을 나타냄. 다국어 지원을 하는 경우 유용하게 사용 |
locales | 사용 가능한 모든 로캘의 목록 |
defaultLocale | 구성된 기본 로캘을 나타냄 |
● 서버 사이드 렌더링 코드(getServerSideProps())
/pages/test.js
import Head from "next/head";
import Link from "next/link";
export async function getServerSideProps(context) {
const s = context.query["s"]; // 아래 내용 참고
const res = await fetch(
`https://jsonplaceholder.typicode.com/comments?postId=${s}`
);
const numberData = await res.json();
return { //정적생성과 같이 return 값 구조 같음
props: {
numberData,
s,
},
};
}
export default function Test({ numberData, s }) {
return (
<>
<Head>
<title>테스트페이지</title>
</Head>
{numberData.map((number) => {
return (
<div
key={number.id}
style={{
border: "1px solid #fff",
marginBottom: "10px",
width: "100%",
}}
>
<h4>postid:{s}</h4>
<h4>{number.name}</h4>
<div>{number.email}</div>
<div>{number.body}</div>
</div>
);
})}
<Link href={"/"}>뒤로가기</Link>
</>
);
}
1. context 속성 : 페이지에 대한 요청을 처리하는 데 필요한 여러 가지 데이터를 포함
params | 동적 라우팅을 사용하는 페이지의 경우 현재 페이지에 대한 경로 매개변수(route parameters)를 포함 ex) [id].js 각 데이터를 매핑해서 id값을 추출해서 params에 등록해준다 (params: { id: 값 }) |
req | HTTP 요청 객체로, 요청에 대한 세부 정보(예: 헤더, 요청 경로 등)를 포함 |
res | HTTP 응답 객체로, 응답을 수정할 수 있는 방법을 제공 |
query | URL 쿼리 문자열이 파싱된 객체 ex) ?s=1 , context.query는 { s : '1' } |
preview | 페이지가 프리뷰 모드(preview mode)에서 렌더링되고 있는지 여부 |
previewData | 프리뷰 모드에서 사용되는 데이터. setPreviewData 함수를 통해 설정된 데이터가 이 속성을 통해 전달 |
locale | 페이지에 설정된 현재 로캘(locale)을 나타냄. 다국어 지원을 하는 경우 유용하게 사용 |
locales | 사용 가능한 모든 로캘의 목록 |
defaultLocale | 구성된 기본 로캘을 나타냄 |
728x90
반응형
'Next.js' 카테고리의 다른 글
[next.js] Head 컴포넌트와 구글폰트 적용하기 (0) | 2023.12.04 |
---|---|
[next.js] Image컴포넌트 (0) | 2023.12.04 |
[next.js] useContext(다크모드) (0) | 2023.12.04 |
[next.js] 리다이렉트(redirects), 커스텀 404 페이지 (0) | 2023.12.04 |
[next.js] useRouter hook (0) | 2023.12.01 |
댓글