1일 1CS(Computer Science)

리액트 동시성 모드(Concurrent Mode)에 관해서 설명해주세요.

표자 2025. 5. 20. 08:41

리액트 동시성 모드란? 🤔

리액트 동시성 모드는 마치 여러 손님이 동시에 주문하는 카페에서 바리스타가 긴급한 주문(중요 UI 작업)을 먼저 처리하는 것과 같습니다! 🏃‍♂️💨

이전 리액트는 단일 스택 구조로 작업했어요. 즉, 한 번 렌더링을 시작하면 모든 작업을 끝까지 완료해야만 했습니다. 마치 하나의 커피를 완성할 때까지 다른 모든 주문을 기다리게 하는 것과 같죠. ☕️⏳

하지만 동시성 모드에서는

  • 작업을 중간에 멈출 수 있음 ⏸️
  • 더 중요한 작업이 들어오면 우선순위 변경 가능 🔄
  • 사용자 경험을 방해하지 않고 백그라운드에서 작업 처리 🔍

 

동시성 모드의 핵심 기능들 🛠️

1. startTransition 🚦

특정 상태 업데이트를 '덜 중요한 작업'으로 표시할 수 있습니다.

import { startTransition } from 'react';

// 검색 입력 시 동작
function handleSearch(e) {
  // 입력값 업데이트는 즉시 반영 (중요!)
  setSearchInput(e.target.value);
  
  // 검색 결과 업데이트는 덜 중요하므로 transition으로 처리
  startTransition(() => {
    setSearchResults(searchFor(e.target.value));
  });
}

2. useDeferredValue 🕰️

값의 업데이트를 지연시켜 불필요한 리렌더링을 방지합니다.

import { useDeferredValue } from 'react';

function SearchResults({ query }) {
  // 입력값이 빠르게 변할 때 지연된 값 사용
  const deferredQuery = useDeferredValue(query);
  
  // deferredQuery가 변경될 때만 결과 계산
  const results = useMemo(
    () => searchFor(deferredQuery),
    [deferredQuery]
  );
  
  return <ResultsList items={results} />;
}

3. useTransition ⚡

상태 업데이트를 transition으로 표시하고 로딩 상태를 확인할 수 있습니다.

import { useTransition } from 'react';

function SearchBar() {
  const [isPending, startTransition] = useTransition();
  const [query, setQuery] = useState('');
  const [results, setResults] = useState([]);
  
  function handleChange(e) {
    setQuery(e.target.value);
    startTransition(() => {
      setResults(searchDatabase(e.target.value));
    });
  }
  
  return (
    <>
      <input value={query} onChange={handleChange} />
      {isPending ? <Spinner /> : <ResultsList items={results} />}
    </>
  );
}

 

동시성 모드가 필요한 상황 🎯

1. 검색 및 필터링 🔍

데이터센터 장비 검색 시스템에서

  • 입력 필드에 타이핑 할 때마다 결과가 필터링됨
  • 동시성 모드 없이는 타이핑할 때마다 UI가 버벅임
  • startTransition을 사용하면 타이핑은 부드럽게, 결과는 준비되는 대로!

2. 대규모 데이터 테이블 렌더링 📊

DCIM 대시보드에서

  • 수천 개의 서버 및 네트워크 장비 정보를 테이블로 표시
  • 실시간 데이터가 주기적으로 업데이트
  • useDeferredValue로 테이블 데이터를 지연 업데이트하면 스크롤과 정렬이 훨씬 부드러워짐

3. 복잡한 양식 처리 📝

FMS(Facility Management System)에서

  • 사용자가 양식을 작성하는 동안 유효성 검사 수행
  • 에러 메시지 표시와 입력 처리를 동시에 해야 함
  • 동시성 모드로 입력은 즉시 반영하고, 에러 메시지는 우선순위를 낮게 설정

동시성 모드 사용 시 주의사항 ⚠️

  1. 효과 타이밍 변화 - useEffect가 지연될 수 있어 타이밍에 민감한 코드는 주의 필요
  2. 렌더링 중복 - 일부 컴포넌트는 여러 번 렌더링될 수 있으므로, 순수 함수로 작성해야 함
  3. 디버깅 복잡성 - 실행 순서가 복잡해져 디버깅이 어려울 수 있음
  4. 모든 곳에 적용 금지 - 성능 최적화가 필요한 부분에만 선택적으로 적용하세요!

 


 

리액트 동시성 모드(Concurrent Mode)에 관해서 설명해주세요.

프론트엔드와 관련된 질문이에요.

리액트의 동시성 모드는 여러 작업을 비동기적으로 동시에 처리하면서도 중간에 더 중요한 작업이 들어오면 우선순위를 바꿔서 그 작업을 먼저 처리하는 기능을 의미합니다. 예전 리액트는 스택 구조로 이루어졌습니다. 즉 한 번 렌더링을 시작하면 끝까지 멈추지 않고 다 처리해야 했습니다. 하지만 동시성 모드에서는 중간에 멈추거나 작업을 잠시 뒤로 미뤄둘 수 있어서 중요한 작업을 먼저 끝낼 수 있게 되었습니다.

이 동시성을 활용하여 리액트는 중요한 작업과 덜 중요한 작업을 나눠서, 덜 중요한 작업은 백그라운드에서 진행하고 중요한 부분은 바로 사용자에게 보여줍니다. 예를 들어 검색창에 뭔가를 입력하고 있을 때, 그에 맞춰 검색 결과가 업데이트되더라도, 리액트가 해당 작업을 백그라운드에서 처리하게 해서 화면이 느려지지 않게 할 수 있습니다.

동시성을 활용한 기능에는 무엇이 있나요? 🤔

첫번째로 startTransition이란 기능을 이용하면 특정 상태 업데이트를 “덜 중요한 작업”으로 분류해서, 사용자가 클릭하거나 입력하는 반응 같은 중요한 업데이트가 우선적으로 처리 됩니다. 또 useDeferredValue라는 훅을 사용하면 값의 업데이트를 잠깐 지연시킬 수 있어서, 사용자가 뭔가 빠르게 입력할 때마다 리렌더링되지 않게 최적화할 수 있습니다.

동시성 모드의 장점은 사용자와 상호작용하는 부분이 훨씬 매끄럽게 느껴진다는 것입니다. 예를 들어, 사용자가 스크롤할 때 다른 무거운 작업이 있다 하더라도, 동시성 모드 덕분에 스크롤이 우선적으로 부드럽게 작동하게 만들 수 있습니다.

동시성 기능을 활용할때 주의할 점은 없을까요? 🧐

주의할 점은 모든 컴포넌트에 이 동시성 모드를 무분별하게 적용하면 오히려 성능이 떨어질 수 있다는 점입니다. 그래서 필요한 부분에만 이 동시성 모드를 잘 활용하는 것이 중요하다고 볼 수 있습니다.

그럼 동시성이 필요한 부분은 언제인가요? 🤔

동시성이 필요한 상황은 주로 사용자와의 상호작용이 빈번하고 응답성이 중요한 경우입니다.

첫 번째 예로, 검색 필터링이나 자동 완성 같은 기능이 있습니다. 사용자가 검색어를 입력할 때마다 결과가 업데이트되는 경우, 모든 입력마다 화면이 리렌더링된다면 앱이 느려지고 입력할 때마다 끊김을 느낄 수 있습니다. 이때 동시성 모드를 사용하면 검색어 입력 자체가 더 중요한 작업이 되어 검색 결과 업데이트는 백그라운드에서 처리되므로, 입력이 빠르고 부드럽게 유지됩니다.

두 번째로, 무거운 데이터나 리스트를 로딩하는 경우에 유용합니다. 예를 들어 긴 스크롤 목록을 보면서 네트워크를 통해 데이터를 로딩할 때, 새로운 항목을 추가로 불러오는 작업보다 사용자가 현재 보고 있는 화면의 스크롤이 더 중요한 작업입니다. 이때 동시성을 사용하면 로딩은 백그라운드로 넘기고, 스크롤을 최우선으로 부드럽게 렌더링할 수 있습니다.

또한, 애니메이션이 포함된 화면 전환이나 중요도가 높은 사용자 입력 작업도 동시성을 고려할 만한 케이스입니다. 사용자가 버튼을 클릭했을 때 UI가 즉각적으로 반응하고, 이후에 비동기 작업이 처리되도록 설정해 주면 클릭 시의 지연 없이 상호작용이 자연스러워집니다.

728x90