본문 바로가기
C.W.K.
Stream
Lesson 03 of 06 · published

스케줄링 직관 — 우선순위, 배칭, yielding

~10 min · scheduling, concurrent, internals

Level 0React 입문자
0 XP0/54 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete
React 스케줄러의 내부 구현을 외울 필요는 없어. 다만 긴급 업데이트와 transition이 화면에 어떻게 반영되는지는 알아야 훅을 제대로 고를 수 있어.

세 가지 우선순위로 생각하기

  • 긴급한 업데이트: 입력, 클릭, controlled input처럼 사용자가 즉시 결과를 기대하는 작업이야.
  • Transition: 큰 결과 목록이나 탭 화면처럼 조금 늦어도 되는 작업이야. React는 브라우저의 반응성을 유지하며 준비해.
  • Suspense: 프로미스가 준비될 때까지 기다리는 작업이야. Transition 안에서는 기존 화면을 유지할 수 있고, 그렇지 않으면 가장 가까운 대체 UI를 보여 줘.

숫자로 우선순위를 직접 정하는 대신 useState, startTransition, use()와 Suspense 중 알맞은 도구를 고르면 의미에 맞는 우선순위가 따라와.

자동 batching

React 19는 같은 이벤트 핸들러나 비동기 콜백 안에서 일어난 여러 상태 업데이트를 묶어 한 번에 렌더링해. 일반적인 코드에서 batching을 직접 제어할 필요는 거의 없어.

브라우저에 양보하기

Transition 렌더링이 길어지면 React는 중간에 브라우저에 제어권을 돌려줘. 그 사이 사용자가 입력하거나 클릭하면 긴급한 작업을 먼저 처리한 뒤 중단했던 transition을 이어 가. 무거운 화면을 준비하는 동안 앱이 멈추지 않는 이유야.

업데이트의 의미는 작성자가 정하고 실제 그리기 시점은 React가 정해. 긴급한 작업과 기다려도 되는 작업을 구분해 표시해. 타이밍을 직접 통제하려고 스케줄러와 싸우지 마.

Concurrent는 여러 JavaScript thread를 만든다는 뜻이 아니야

React는 브라우저의 한 main thread에서 렌더링 작업을 작은 단위로 나누고, 더 긴급한 입력이 오면 낮은 우선순위 작업을 잠시 멈출 수 있어. 준비가 끝난 결과만 commit하므로 사용자는 중간 트리를 보지 않아.

배칭은 가까운 상태 변경을 한 렌더링으로 묶어

이벤트 핸들러와 비동기 callback 안의 여러 setter가 한 번의 commit으로 합쳐질 수 있어. DOM을 즉시 읽어야 하는 아주 드문 경우에는 flushSync로 먼저 commit할 수 있지만, 렌더링을 늘리고 concurrent scheduling을 막으므로 기본 도구로 쓰면 안 돼.

Urgent update에는 입력과 클릭 피드백이, transition에는 큰 목록과 route 결과처럼 조금 늦어도 되는 화면이 들어가. 우선순위는 데이터의 중요도가 아니라 사용자가 지금 기다리는 상호작용을 기준으로 정해.

Code

배칭이 실전에 어떻게 보이는지·tsx
function MultiState() {
  const [a, setA] = useState(0);
  const [b, setB] = useState(0);
  const [c, setC] = useState(0);

  function onClick() {
    // 셋 다 한 렌더로 배칭 — React 19 자동.
    setA((x) => x + 1);
    setB((x) => x + 1);
    setC((x) => x + 1);
  }

  console.log("Render"); // 클릭당 한 번 로그, 세 번 아님
  return <button onClick={onClick}>Click ({a + b + c})</button>;
}

External links

Exercise

useState가 세 개인 컴포넌트를 만들고 한 클릭 handler에서 setter를 모두 호출해. 컴포넌트 본문의 로그로 한 번만 렌더링되는지 확인한 다음, 두 setter 사이에 flushSync를 넣어 commit 수가 어떻게 달라지는지 관찰하고 원래 코드로 복원해.
Hint
flushSync는 react-dom에서 가져와. 렌더링이 늘어난 이유와, DOM을 즉시 읽는 요구가 없다면 batching을 유지하는 편이 나은 이유를 함께 적어.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.