긴 작업 분할

웹 기능: Scheduler API

과도한 계산이나 긴 루프는 기본 스레드를 차단하여 페이지가 응답하지 않게 만들 수 있습니다. 이를 방지하려면 주기적으로 브라우저에 제어권을 다시 넘겨야 합니다. scheduler.yield() API를 사용하면 긴 작업을 일시중지하고 브라우저가 사용자 입력 또는 렌더링을 처리한 후 계속 진행할 수 있습니다.

긴 작업 분할

비동기 함수 내에서 scheduler.yield()를 사용하여 작업을 분할합니다.

async function processLargeArray(items) {
  // DO: Set a time-based deadline 50 milliseconds into the future. 50
  // milliseconds is the boundary for when a task becomes a long task.
  let deadline = performance.now() + 50; // 50ms budget

  for (const item of items) {
    // Process the item
    processItem(item);
    
    // MANDATORY: Yield to the main thread periodically to keep the UI
    // responsive. This can be done by checking if the deadline set earlier
    // has been exceeded. When it has been, yield, then reset the deadline
    // another 50 milliseconds into the future.
    if (performance.now() >= deadline) {
      await scheduler.yield();
      deadline = performance.now() + 50;
    }
  }
}

대체 전략

일부 브라우저는 scheduler API를 지원하지 않을 수 있습니다. 코드가 중단 없이 실행되도록 하려면 setTimeout를 사용하여 대체 기능을 구현해야 합니다(MUST).

scheduler.yield()의 대체

async function processLargeArrayWithFallback(items) {
  // DO: Set a time-based deadline 50 milliseconds into the future.
  let deadline = performance.now() + 50;

  for (const item of items) {
    processItem(item);
    
    // MANDATORY: Yield to the main thread periodically to keep the UI responsive.
    if (performance.now() >= deadline) {
      // DO: Feature detect scheduler.yield
      if ('scheduler' in window && 'yield' in window.scheduler) {
        await scheduler.yield();
      } else {
        // DO: Fallback to setTimeout for older browsers
        await new Promise(resolve => setTimeout(resolve, 0));
      }
      deadline = performance.now() + 50;
    }
  }
}