반응형
📝Server Component (SSR)
서버에서 자바스크립트 파일을 읽어 HTML을 만든 후 클라이언트에게 전달한다 Next에서는 기본적으로 App Router에서 서버 사이드 렌더링을 적용시키고 있다 만약 명시적으로 표현하려면 “use server”를 상단에 적어주면 된다
📝동작과정
- 서버에서 자바스크립트를 읽고 HTML 생성
- 클라이언트에게 보내 Javascript(이벤트 핸들러)와 Hydration한다
- 이부분이 좀 이상한 게 있는데 server component를 사용하면 useState, onClick등과 같은 클라이언트에서 사용하는 이벤트 핸들러 따위를 사용할 수가 없다 고로 Hydration이 불가능해보이는데 잘 모르겠다
📝이점
- Data Fetch
- 렌더링에 필요한 데이터를 가져오는데 걸리는 시간과 클라이언트가 수행하는 요청 양을 줄일 수 있다
- 보안
- 네트워크에 잡히지 않기 때문에 어떤 URL로 HTTP 통신했는지 보이지 않습니다
- 캐싱 (deafult 캐싱 이용)
- 서버에서 렌더링하면 결과를 캐시하기 때문에 비용이 절감 될 수 있습니다.
await fetch('<http://localhost:8080/next>', {cache: 'force-cache'});
(캐싱전) → [1] interval 51, [2] interval 57
(캐싱후) → [1] interval 2, [2] interval 2
- 번들 크기
- 서버에서 그려서 주기 때문에 클라이언트가 서버 구성 요소용 JavaScript를 다운로드, 구문 분석 및 실행할 필요가 없기 때문에 인터넷 속도가 느리거나 성능이 떨어지는 장치를 사용하는 사용자에게 유용
- 스트리밍
📝서버 렌더링
정적, 동적, 스트리밍의 세 가지 하위 집합이 존재한다
- 정적 렌더링
- 정적 렌더링을 사용하면 경로는 빌드 시 렌더링되거나 데이터 재검증 후 백그라운드에서 렌더링
- 정적 렌더링은 경로에 사용자에게 개인화되지 않은 데이터가 있고 정적 블로그 게시물이나 제품 페이지와 같이 빌드 시 알 수 있는 데이터가 있는 경우 유용하다
- 동적 렌더링
- 동적 렌더링은 경로에 사용자에게 맞춤화된 데이터가 있거나 쿠키나 URL의 검색 매개변수와 같이 요청 시에만 알 수 있는 정보가 있는 경우 유용하다
- 스트리밍
- 서버에서 알아서 청크사이즈로 분리 후에 병렬로 처리해준다
Next.js가 사용된 기능과 API를 기반으로 각 경로에 가장 적합한 렌더링 전략을 자동으로 선택하므로 정적 렌더링과 동적 렌더링 중에서 선택할 필요가 없습니다
📝Client Component (CSR)
클라이언트에서 받은 Javascript를 해석해 HTML을 렌더링하는 방식으로 “use client” 지시어를 명시해야 사용이 가능하다 해당 지시어를 사용해야 useState같은 훅과 이벤트 핸들링이 사용 가능하다
📝동작과정
- 서버에서 HTML을 렌더링할 수 있게 자바스크립트 번들링을 보낸다
- 자바스크립트를 읽어 클라이언트에서 웹 브라우저가 그리기 시작한다
- use client라고 해도 React처럼 아예 안 그리는 수준이 아니라 어느정도 그릴 순 있는 건 다 그려서 나온다 (개발자 도구에서 네트워크의 HTML을 확인해보면 알 수 있다)
- 이벤트 핸들링따위와 연결 할 수 있게 Hydration을 한다
📝SSR / CSR 주의사항
- page.tsx가 use client면 포함되어있는 컴포넌트들도 client side rendering을 한다 → console.log 사용시 서버에 찍히는지 콘솔창에 찍히는지로 판단 가능
- page.tsx가 use client일 때 하위 컴포넌트 use clinet 선언 안 해도 Hook 사용 가능 (알아서 지정해주는 것 같음)
- use client만 아니면 A컴포넌트는 서버렌더링 B컴포넌트는 클라이언트 렌더링 나눌 수 있다하지만 page가 use client의 경우 하위 컴포넌트가 서버 렌더링하면 왜인지 모르겠다만 엄청나게 data fetch를 요청한다
- SSR과 CSR 어떤게 동작한 지 궁금할 시 개발자도구 네트워크를 보면 SSR의 경우 서버에서 데이터 Fetch를 하기 때문에 잡히지 않고 CSR의 경우 잡힌다
- 번들 크기를 줄이기 위해서는 클라이언트와 서버쪽에서 부담을 잘 분배해야한다
- layout은 서버 컴포넌트로 두고 사용자의 이벤트 핸들링 따위가 들어간 컴포넌트의 경우는 따로 클라이언트 컴포넌트로 정의한다
- 서버 구성요소를 클라이언트 요소로 가져오기는 지원되지 않지만 꼭 되게 하려면 {children}으로 받을 수 있다
/** ClientComponent **/
'use client'
// You cannot import a Server Component into a Client Component.
import ServerComponent from './Server-Component'
export default function ClientComponent({
children,
}: {
children: React.ReactNode
}) {
const [count, setCount] = useState(0)
return (
<>
<button onClick={() => setCount(count + 1)}>{count}</button>
<ServerComponent />
</>
)
}
/** ClientComponent **/
'use client'
import { useState } from 'react'
export default function ClientComponent({
children,
}: {
children: React.ReactNode
}) {
const [count, setCount] = useState(0)
return (
<>
<button onClick={() => setCount(count + 1)}>{count}</button>
{children}
</>
)
}
/** Page.tsx **/
import ClientComponent from './client-component'
import ServerComponent from './server-component'
// Pages in Next.js are Server Components by default
export default function Page() {
return (
<ClientComponent>
<ServerComponent />
</ClientComponent>
)
}
- 어떤 구성 요소를 사용해야할까? (서버 구성요소 / 클라이언트 구성요소)
반응형
'[Next.js] > [Next 14]' 카테고리의 다른 글
[Next 14] 정적 데이터, 이미지, 폰트, 스크립트, 정적 메타데이터, Opengraph, 동적 메타데이터 (1) | 2024.01.02 |
---|---|
[Next 14] 외부 라이브러리, 런타임(Runtime), CSS Style (0) | 2024.01.02 |
[Next 14] 미들웨어 (Middleware) (0) | 2024.01.02 |
[Next 14] 로딩, 서스펜스, 스트리밍 (0) | 2024.01.01 |
[Next 14] Next.js란, 폴더 및 파일 구조, 라우팅, 링크(페이지 연결), 정적 페이지 생성(SSG), 에러 핸들링 (0) | 2024.01.01 |