-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
1 changed file
with
165 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,165 @@ | ||
# Next.js 13과 리액트 18 | ||
|
||
|
||
|
||
## app 디렉토리의 등장 | ||
|
||
기존 pages/ 구조에서는 공통 레이아웃 작업에 한계가 있었다. 예를 들어, 홈, 장바구니, 상품 페이지의 레이아웃이 다를 경우 _app.tsx에서 분기 처리를 해서 처리해야 했다. | ||
|
||
app 디렉토리 구조에서는 `layout.tsx`가 하위 라우트의 레이아웃을 구성한다. | ||
|
||
|
||
|
||
## 리액트 서버 컴포넌트 | ||
|
||
### 기존 리액트 컴포넌트의 한계 | ||
|
||
* 번들 사이즈 - mdx, sanitize-html 등의 라이브러리를 사용한다면, 번들 사이즈가 크게 증가할 수 있다 - 로딩시간 지연 | ||
|
||
* 보안 상의 이유로 db 데이터 접근 불가 | ||
|
||
* 자동 코드 분할 불가 - lazy를 활용해야 함 | ||
|
||
* 컴포넌트, 네트워크 `워터폴` 요청 발생, 기존 컴포넌트에서는 사용자와 서버의 물리적 거리로 waterfall 발생 시, 더욱 오랜 시간 기다려야 했다. | ||
|
||
이에 반해, rsc 구조에서는 물리적 거리가 짧아서 워터폴 지연 현상이 적다. | ||
|
||
<img src="/Users/changwan-woo/Downloads/KakaoTalk_Photo_2024-02-12-18-40-56.jpeg" width="60%" align="left" /> | ||
|
||
|
||
|
||
### 서버 컴포넌트란? | ||
|
||
* 서버와 클라이언트 모두에서 컴포넌트를 렌더링할 수 있는 기법 | ||
|
||
* 서버 컴포넌트는 어떻게 사용자에게 보여질까? | ||
|
||
server component는 json like format으로 직렬화되어, 사용자에게 전달한다. | ||
|
||
* 클라이언트에서 서버 컴포넌트를 사용할 수 없다. | ||
|
||
* 왜 제한해놓았을까? | ||
|
||
* Client component에서 server component를 import할 때, 아래와 같은 구조를 상상해보자. | ||
|
||
<img src = "/Users/changwan-woo/Library/Application Support/typora-user-images/image-20240212201355477.png" width=50% align="left"/> | ||
|
||
이런 구조에서는 사용자가 타이핑을 칠 때마다(client component), 서버 컴포넌트 리렌더링이 발생한다. 하지만, server component는 클라이언트 번들에 포함되어 있지 않다. 따라서 매 렌더링마다 서버에 요청을 할 것이고, 큰 비효율로 이어진다. | ||
|
||
|
||
|
||
|
||
#### 서버 컴포넌트 | ||
|
||
요청이 오면 그 순간 서버에서 한 번 실행된다. 따라서 상태(state)를 가질 수 없고, 렌더링 생명주기(리렌더링)도 일어나지 않는다. | ||
|
||
#### 클라이언트 컴포넌트 | ||
|
||
우리에게 친숙한 기존 컴포넌트. Next.js 13이전에 모든 컴포넌트는 클라이언트 컴포넌트이다. | ||
|
||
#### Shared 컴포넌트 | ||
|
||
서버와 클라이언트 모두에서 사용할 수 있는 컴포넌트, 서버 컴포넌트의 제약을 함께 가지는 만큼 상태를 가질 수 없다. | ||
|
||
```jsx | ||
return ( | ||
<div> | ||
Shared component | ||
</div> | ||
) | ||
``` | ||
|
||
#### 기존 SSR의 한계 | ||
|
||
특히, Nextjs의 종속된 문법을 사용해야 된다는 점 때문에 꼭 server에서 처리해야 할 로직이 아니라면, SSR 선호하지 않는다. | ||
|
||
* Next.js의 종속된 문법을 사용해야 한다. | ||
|
||
* hydration이 항상 일어난다. (getServerSideProps) | ||
|
||
### RSC 구조 | ||
|
||
React server component는 아래와 같이 JSON like format으로 브라우저에 전달된다. | ||
|
||
* 왜 JSON 이 아니고 like, JSON like 일까? | ||
|
||
JavaScript의 function은 non-serializable한 객체이다. 따라서, JSON.derserialize와 같은 방법을 사용하지 못하고, JSON like 형식을 구성한 뒤 전달한다. | ||
|
||
![image-20240213211706438](/Users/changwan-woo/Library/Application Support/typora-user-images/image-20240213211706438.png) | ||
|
||
|
||
|
||
### Streaming SSR과 RSC | ||
|
||
#### 기존 SSR | ||
|
||
<img src="/Users/changwan-woo/Library/Application Support/typora-user-images/image-20240213214606637.png" width="50%" align="left" /> | ||
|
||
|
||
|
||
#### Streaming SSR | ||
|
||
Streaming SSR은 Suspense와 함께 기존 SSR의 한계를 해결하였다. SSR은 data fetching에 걸리는 시간 동안 사용자가 빈 화면을 보고 있어야 했다. Streaming SSR은 비동기 작업(data fetching)을 진행하는 동안, Suspense placeholder, Suspense로 나뉘어진 컴포넌트 등을 chunk단위로 나누어 클라이언트에 전송한다. 따라서, 기존 SSR에 비해 훨씬 더 TTFB, FCP등을 보장할 수 있다. | ||
|
||
<img src="/Users/changwan-woo/Library/Application Support/typora-user-images/image-20240213214457920.png" width="50%" align="left" /> | ||
|
||
|
||
|
||
### TurboPack | ||
|
||
Next.js에서 왜 esbuild, rspack과 같은 번들, 빌드 도구를 활용할 수 없을까 의문이었는데 Turbopack이 곧 릴리즈된다. | ||
|
||
https://areweturboyet.com/ | ||
|
||
|
||
|
||
### Server action | ||
|
||
더 본질적으로 질문하면 왜 서버에서 action을 해야될까? | ||
|
||
* mutation을 발생시키는 컴포넌트들의 번들 사이즈 감소가 복잡성을 증가시키면서까지 큰 이점이 있을까? | ||
|
||
아직까지는 복잡성으로 인한 단점들이 더 커보이지만 사용해봐야 정확히 알 수 있을 것 같다. | ||
|
||
서버컴포넌트는 앞서 살펴보았듯이 상태를 가질 수 없다. 따라서 React 19에 발표될 아래 hook들과 같이 사용될 것이다. | ||
|
||
`useFormStatus()`,` `useFormState( )` | ||
|
||
|
||
|
||
## RSC에 오해 | ||
|
||
이번에 Server component를 공부하기 전까지 Server 가 있어야 사용할 수 있다고 생각했다. (사실 Server component 오해 사기 좋은 이름을 지은 리액트 팀의 탓도 있지 않을까?) | ||
|
||
이러한 오해 때문에 Vercel lock-in되지 않을까 생각하며 이전까지 RSC에 대해서 부정적으로 생각했었다. 하지만, React server component는 서버 없이도 동작하며, 빌드 타임에 JSON like format을 생성한다. 따라서 S3에 배포해도 SSG와 같은 방식으로 동작한다. | ||
|
||
정리하자면, Client 환경에서는 SSG로 동작, Server 환경에서는 SSR+RSC로 동작한다고 이해할 수 있다. | ||
|
||
https://twitter.com/dan_abramov2/status/1745794290679259635 | ||
|
||
|
||
|
||
## RSC에 대한 개인적인 생각 | ||
|
||
useEffect의 명령형 코드를 async 컴포넌트가 지원되면서 훨씬 더 깔끔한 멘탈 모델을 제공하고 있다. | ||
|
||
기존에는 Streaming SSR을 구현하기가 매우 어려웠는데 SSR의 단점을 해결하는 Streaming SSR을 손 쉽게 구현할 수 있다는 점이 긍정적이다. | ||
|
||
|
||
|
||
## 참조 | ||
|
||
https://www.plasmic.app/blog/how-react-server-components-work | ||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|