sbyeol3/articles

[정리] RFC: React Server Components

Opened this issue · 0 comments

2021.12.21 원문

요약

  • 서버에서 동작하기 때문에 번들사이즈에 전혀 영향을 주지 않는다.
    • Server Components 코드는 클라이언트에 다운로드 되지 않기 때문에 번들 사이즈가 감소하며 이에 따라 초기 시간 감소에 영향을 준다.
  • 데이터베이스나 파일시스템과 같은 server-side 데이터 자원에 접근할 수 있다.
  • 기존에 사용하던 React 컴포넌트와 같은 Client Components와 통합 가능하다.
    • Server Components는 데이터를 서버에서 로드하여 클라이언트단에 props로 해당 데이터를 전달한다.
  • render할 Client Components를 다이내믹하게 선택함으로써 필요한 코드만 최소한으로 다운로드받게끔 한다.
  • reload될 때 client state를 보존한다.
    • Server Component tree가 refetch되더라도 클라이언트의 상태, 포커스, 진행중인 애니메이션을 방해하지 않는다.
  • Server Component는 UI 렌더링 단위를 클라이언트로 점진적으로 스트리밍하여 렌더링된다. (Suspense와의 결합)
  • 서버와 클라이언트 간의 코드를 공유할 수 있다.

Motivation

  • 근본적인 문제 : React app은 client 중심이며 서버를 충분히 활용할 수 없다는 것

Zero-Bundle-Size 컴포넌트

  • 서드파티 패키지를 사용하는 것은 편리하지만 코드 사이즈를 증가시키며 성능에 부정적인 효과를 가져온다. 그렇다고 해서 기능들을 직접 작성하는 것은 시간이 많이 소요되며 제대로 동작하지 않을 염려가 있다. tree-shaking과 같은 기능도 있지만, 그럼에도 추가적인 코드를 사용자에게 전달해야만 한다.
// NoteWithMarkdown.server.js - Server Component === zero bundle size

import marked from 'marked'; // zero bundle size
import sanitizeHtml from 'sanitize-html'; // zero bundle size

function NoteWithMarkdown({text}) {
  const html = sanitizeHtml(marked(text));
  return (/* render */);
}
  • Server Component는 개발자가 서버에 static한 컨텐츠를 렌더링하게 함으로써 React의 장점을 최대한 활용하면서도 번들 사이즈에 영향을 미치지 않게 한다.

Full Access to the Backend

  • React app을 만들 때의 가장 일반적인 문제 : 데이터에 접근하는 방법이나 데이터를 처음 저장할 위치를 결정하는 것
  • 개발자들은 UI를 강화하고자 추가적인 엔드포인트를 노출해야 하거나 또는 UI를 염두에 두지 않은 엔드포인트를 사용해야 한다.
  • 파일 시스템에서 데이터를 가져올 수도 있고, 마이크로서비스 등의 기타 백엔드에 바로 접근하여 데이터 자원을 사용할 수 있다.

Automatic Code Splitting

  • Code splitting : app을 작은 번들 여러 개로 나누어 클라이언트에 적은 코드만을 보낼 수 있도록 하는 기법
  • 일반적인 접근법 : route마다 번들을 lazy하게 로드하거나 런타임 시 각 기준에 따라 다른 모듈을 lazy하게 로드
  • 성능을 향상하는 데 분명 좋으나 한계점이 존재
    1. 개발자가 일반적인 import 문을 React.lazy로 수정해야 함
    2. 선택된 컴포넌트가 로딩되는 시점을 지연시킴으로써 적은 코드를 로드하는 이점이 상쇄됨
  • Server Component는 이 문제를 어떻게 해결하는가?
    1. 클라이언트 컴포넌트의 모든 import를 code-split 지점의 가능성으로 간주함
    2. 어떤 컴포넌트를 선택할지 서버에서 더 일찍 결정하여 렌더링 프로세스 초기에 다운로드가 가능하게 함

No Waterfalls

  • 나쁜 성능은 데이터를 fetch하는 것을 순차적으로 할 때 흔하게 발생한다.
  • 로직을 서버로 옮김으로써 request latency를 줄이고 성능을 향상시킨다.

Avoiding the Abstraction Tax

  • "정적인" 언어를 사용하는 UI 프레임워크는 추상화 중 일부를 컴파일하기 위해 미리 컴파일을 할 수 있지만 JS는 가능하지 않다.
  • 추상화 비용을 서버에 옮겨서 이 문제를 해결한다.

Distinct Challenges, Unified Solution

  • 순수한 서버렌더링, 클라이언트 렌더링은 충분하지 않다.
  • 서버 렌더링와 클라이언트 렌더링은 보통 기술 을 mixing 해야만 한다. 그러나 서버 컴포넌트는 동일한 언어, 동일한 프레임워크, 응집력 있는 API 집합을 사용하며 서버, 클라이언트 렌더링이 가능하다.