React 18 Beta의 Automatic Batching 적용기
배경
프로젝트에서 복잡한 폼 처리 로직이 성능 이슈를 일으키고 있었다. 여러 상태를 연속으로 업데이트할 때마다 리렌더링이 발생해 UX가 버벅이는 문제가 있었다. React 18 Beta가 공개되면서 Automatic Batching 기능이 이 문제를 해결할 수 있을 것 같아 테스트 프로젝트에 적용해봤다.
기존 문제
const handleSubmit = async () => {
setLoading(true); // 렌더링 1
setError(null); // 렌더링 2
const result = await api.submit(data);
setData(result); // 렌더링 3
setLoading(false); // 렌더링 4
};
React 17에서는 이벤트 핸들러 내부의 동기 코드만 자동 배칭이 되고, Promise나 setTimeout 내부의 상태 업데이트는 각각 렌더링을 트리거했다.
React 18 Beta 적용
React 18에서는 모든 상태 업데이트가 자동으로 배칭된다. 위 코드를 그대로 사용해도 불필요한 렌더링이 줄어들었다.
// React 18에서는 자동으로 배칭됨
const result = await api.submit(data);
setData(result);
setLoading(false);
setError(null);
// 단 한 번의 렌더링만 발생
만약 즉시 렌더링이 필요한 경우 flushSync를 사용할 수 있다.
import { flushSync } from 'react-dom';
flushSync(() => {
setCounter(c => c + 1);
});
// DOM 즉시 업데이트됨
결과
프로파일러로 측정한 결과 폼 제출 시 렌더링 횟수가 4회에서 1회로 줄었다. 체감 성능 개선도 확실했다. 다만 아직 Beta 단계라 프로덕션 적용은 보류했고, 정식 릴리즈를 기다리는 중이다.
참고
- 기존
unstable_batchedUpdates사용 코드는 제거 가능 - Concurrent Features를 사용하지 않아도 Automatic Batching은 적용됨
- 18 마이그레이션 가이드 숙지 필요