React 18 useTransition으로 검색 입력 성능 개선하기

문제 상황

5000개 이상의 상품 데이터를 검색하는 기능에서 입력할 때마다 UI가 버벅이는 문제가 발생했다. 검색어를 입력할 때마다 전체 리스트를 필터링하면서 렌더링이 블로킹되었다.

const [searchTerm, setSearchTerm] = useState('');
const filteredProducts = products.filter(p => 
  p.name.includes(searchTerm)
);

// 입력할 때마다 5000개 필터링 + 렌더링
<input onChange={(e) => setSearchTerm(e.target.value)} />

useTransition 적용

React 18에서 정식 출시된 useTransition을 사용해 검색어 업데이트를 낮은 우선순위로 처리했다.

const [searchTerm, setSearchTerm] = useState('');
const [query, setQuery] = useState('');
const [isPending, startTransition] = useTransition();

const handleChange = (e) => {
  setSearchTerm(e.target.value); // 즉시 반영
  startTransition(() => {
    setQuery(e.target.value); // 낮은 우선순위
  });
};

const filteredProducts = products.filter(p => p.name.includes(query));

결과

입력 필드는 즉시 반응하고, 필터링 결과는 약간 지연되어 표시된다. 사용자는 타이핑이 끊기지 않아 훨씬 자연스럽게 느껴진다고 피드백을 받았다.

isPending 상태로 로딩 표시를 추가할 수 있지만, 이 케이스에서는 지연이 크지 않아 생략했다.

debounce와 다르게 즉각적인 피드백을 유지하면서도 무거운 업데이트를 뒤로 미룰 수 있다는 점이 React 18의 강점이었다.