React 18 베타 Concurrent Rendering 적용 후기

배경

지난달부터 React 18 베타가 공개되면서 Concurrent Rendering을 실험해볼 수 있게 됐다. 사용자 수가 적은 사내 대시보드 프로젝트에 먼저 적용해봤다.

마이그레이션

기존 ReactDOM.rendercreateRoot로 교체하는 것부터 시작했다.

// Before
import ReactDOM from 'react-dom';
ReactDOM.render(<App />, document.getElementById('root'));

// After
import { createRoot } from 'react-dom/client';
const root = createRoot(document.getElementById('root'));
root.render(<App />);

Suspense for Data Fetching

가장 기대했던 부분은 Suspense를 데이터 페칭에 사용하는 것이었다. 기존 로딩 상태 관리 로직을 대체할 수 있었다.

<Suspense fallback={<Spinner />}>
  <UserList />
</Suspense>

다만 아직 React Query나 SWR 같은 라이브러리들의 공식 지원이 완벽하지 않아서, 일부 컴포넌트만 적용했다.

useTransition으로 UX 개선

검색 필터링이 무거운 테이블에서 useTransition을 사용해 입력 딜레이를 줄였다.

const [isPending, startTransition] = useTransition();

const handleSearch = (value) => {
  startTransition(() => {
    setSearchTerm(value);
  });
};

입력은 즉시 반영되고 테이블 렌더링은 백그라운드로 처리되면서 체감 성능이 확실히 좋아졌다.

겪은 문제

일부 서드파티 라이브러리에서 ReactDOM.render 관련 경고가 발생했다. 베타 단계라 예상했던 부분이지만, 프로덕션 적용은 아직 이르다는 판단이다.

정리

Concurrent Rendering은 분명 체감되는 성능 개선을 가져왔다. 특히 무거운 렌더링 작업이 있는 경우 useTransition이 유용했다. 다만 생태계 지원을 지켜보며 점진적으로 도입하는 게 현실적일 것 같다.

React 18 베타 Concurrent Rendering 적용 후기