react에서 batching이란?
React에서 batching는 구성 요소의 다시 렌더링을 트리거하기 전에 여러 상태 업데이트를 그룹화하는 전략을 나타낸다.
각 리렌더링은 계산 비용이 많이 들 수 있기 때문에 이러한 최적화는 필수적이다.
특히 대규모 가상 DOM 트리가 있는 복잡한 구성 요소에서는 더욱 그렇다.
React 18 이전의 automatic batching은 제한적으로 적용되었다.
적용 범위:
주로 React의 이벤트 핸들러 내에서만 자동으로 발생했다.
예를 들어, onClick, onChange 등의 React 이벤트 핸들러 내에서 발생하는 상태 업데이트에 대해서만 자동 배칭이 적용되었다.
제한사항:
Promise, setTimeout, setInterval, 네이티브 이벤트 핸들러 등에서는 자동 배칭이 적용되지 않았다.
이런 비동기 작업에서 여러 상태 업데이트가 발생할 경우,
각 업데이트마다 별도의 리렌더링이 발생했다.
예시:
function handleClick() {
setCount(c => c + 1);
setFlag(f => !f);
}
// 하나의 리렌더링만 발생
// setTimeout 내부 - 자동 배칭 미적용
setTimeout(() => {
setCount(c => c + 1);
setFlag(f => !f);
}, 0);
// 두 번의 리렌더링 발생
수동 배칭:
비동기 작업에서 배칭을 원할 경우,
ReactDOM.unstable_batchedUpdates() API를 사용해야 했다.
ReactDOM.unstable_batchedUpdates(() => {
setCount(c => c + 1);
setFlag(f => !f);
});
성능 영향:
이벤트 핸들러 외부에서 발생하는 여러 상태 업데이트로 인해 불필요한 리렌더링이 발생할 수 있었다.
이는 특히 대규모 애플리케이션에서 성능 저하를 야기할 수 있었다.
적용 범위 확대:
모든 상태 업데이트에 대해 자동 배칭이 적용된다.
React 이벤트 핸들러뿐 아니라 Promise, setTimeout, setInterval, 네이티브 이벤트 핸들러 등에서도 작동한다.
일관된 동작:
코드의 위치에 관계없이 모든 상태 업데이트가 일관되게 배치 처리된다.
예시:
// React 18에서는 모두 하나의 리렌더링만 발생
setTimeout(() => {
setCount(c => c + 1);
setFlag(f => !f);
setText('updated');
}, 0);
fetch('/api').then(() => {
setCount(c => c + 1);
setFlag(f => !f);
setText('updated');
});
성능 향상:
불필요한 리렌더링이 크게 줄어들어 전반적인 애플리케이션 성능이 향상된다.
opt-out 옵션:
필요한 경우 ReactDOM.flushSync()를 사용하여 특정 업데이트에 대해 배칭을 비활성화할 수 있다.
ReactDOM.flushSync(() => {
setCount(c => c + 1);
});
// 이 시점에서 즉시 리렌더링 발생
setFlag(f => !f);
사용 방법:
React 18을 사용하고 있다면 별도의 설정 없이 자동으로 적용된다.
createRoot API를 사용하여 애플리케이션을 렌더링해야 한다.
import { createRoot } from 'react-dom/client';
const root = createRoot(document.getElementById('root'));
root.render(<App />);
코드 단순화: 더 이상 수동으로 배칭을 관리할 필요가 없다.
예측 가능성 향상: 상태 업데이트의 동작이 더 일관되고 예측 가능해진다.
성능 최적화: 개발자의 추가 작업 없이도 자동으로 성능이 개선된다.
React 18의 automatic batching은 개발자 경험을 개선하고 애플리케이션의 성능을 향상시키는 중요한 기능 중 하나다.
이를 통해 React 애플리케이션의 효율성과 반응성이 전반적으로 개선된다.
what-is-automatic-batching-in-react-18
nukw0n-dev.tistory
공식 문서
모아서 해? 나눠서 해?