[React] ServerComponent, HTML Streaming
1. Server Components VS ClientComponent
: React 프레임워크의 새로운 기능 중 하나입니다. 이 기능은 서버와 클라이언트 간의 데이터 및 렌더링 로직을 효과적으로 분리하여 성능을 향상시킬 수 있는 방법을 제공합니다.
React v18 버전 이전까지는 React를 사용하여 어플리케이션을 렌더링하는 주요한 방법이 "전적으로(entirely)" 클라이언트에 있었다.
서버 컴포넌트와 클라이언트 컴포넌트의 가장 큰 차이점은 컴포넌트가 렌더링되는 장소가 서버냐 클라이언트냐의 차이입니다.
서버 컴포넌트는 서버에서 한차례 해석된 이후 클라이언트로 전달되고, 클라이언트 컴포넌트는 클라이언트가 js 번들을 다운로드 받은 후 해석하게 됩니다.
2. HTML Streaming
React v18에서의 주요 변경점 중 하나가 HTML Streaming과 점진적인 Hydration입니다
개발자들은 Server Side 단에서 먼저 정적 페이지를 렌더링하고 JS파일들도 번들링한 후에 둘다 Client Side로 보내주는 생각을 해냈다. 하지만 그 DOM에는 동적인 이벤트가 하나도 없는 메마를 상태일 것이다. 그래서 이 메마른 뼈대에 수분을 보충해서, 즉 HTML 코드와 JS 코드를 서로 매칭시켜 동적인 웹사이트를 브라우저에 랜더링하는 기술이 등장했는데 이게 바로
Hydratation이다. 그래서 Hydration을 한글로 직역하면 수분 보충이라고 말 할 수 있다.
v18에서부터는 pipeToNodeWritable를 이용해 html 코드를 스트리밍 형식을 통해 작은 청크 형태로 나누어 보내줄수 있습니다.
// src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { Readable } from 'stream';
const App = () => {
return (
<div>
<h1>Hello, Server-side Rendering!</h1>
<p>This content will be rendered on the server.</p>
</div>
);
};
const stream = new Readable({
read() {},
});
ReactDOM.createRoot(
document.getElementById('root')
).render(
<React.Suspense fallback="Loading...">
<App />
</React.Suspense>,
{
unstable_isConcurrent: true,
unstable_suspenseConfig: { timeoutMs: 5000 },
unstable_strictModeConfig: { unstable_disableIsInputPending: false },
},
// pipeToNodeWritable로 스트림 전송
stream
);
// 서버로 스트림 전송
stream.pipe(process.stdout);
3. React 마운트 과정
1. 함수 컴포넌트 호출
2. 구현부 실행
- props 취득, hook 실행, 내부 변수 및 함수 생성
- 단, hook 에 등록해둔 상태값, 부수함수 효과 등은 별도 메모리에 저장되어 관리된다.
3. return 실행
- 렌더링 시작
4. 렌더 단계(Render Phase)
- 가상DOM을 생성한다.
5. 커밋 단계(Commit Phase)
- 실제 DOM에 반영한다.
6. useLayoutEffect
- 브라우저가 화면에 Paint 하기 전에, useLayoutEffect에 등록해둔 effect(부수효과함수)가 '동기'로 실행된다.
- 이 때, state, redux store 등의 변경이 있다면 한번 더 재렌더링 된다.
7. Paint
- 브라우저가 실제 DOM을 화면에 그린다. didMount가 완료된다.
8. useEffect
- Mount되어 화면이 그려진 직후, useEffect에 등록해둔 effect(부수효과함수)가 '비동기'로 실행된다.
https://velog.io/@timosean/Server-component-vs.-Client-Component
https://react.dev/reference/react-dom/client/hydrateRoot#hydrating-server-rendered-html
https://curryyou.tistory.com/486
https://velog.io/@9rganizedchaos/React-Server-Components%EB%A5%BC-%EC%9D%B4%ED%95%B4%ED%95%B4%EB%B3%B4%EC%9E%90