Scheduler API를 사용하여 자바스크립트에서 작업 실행의 우선순위를 지정하고 제어하여 성능과 사용자 경험을 개선하는 법을 알아보세요.
원문 : https://www.trevorlasn.com/blog/javascript-scheduler-api
자바스크립트의 Scheduler API는 웹 앱에서 작업 우선순위를 관리할 수 있는 표준화된 접근 방식을 도입했습니다.
자바스크립트 개발자들은 오래전부터 메인 스레드에 작업을 양보하기 위해 setTimeout(0)
에 의존해 왔지만, 새로운 Scheduler API를 통해 작업을 언제 어떻게 실행할지 더 세밀하게 제어할 수 있습니다.
메인 스레드에 위임하기 위해 사용했던 전통적인 setTimeout
접근 방식은 세분화된 제어와 적절한 우선순위 관리 기능이 부족했습니다. Scheduler API는 보다 강력한 해결책을 제공함으로써 이러한 단점을 해결합니다.
// setTimeout을 사용한 기존 접근 방식
setTimeout(() => {
processNextBatch();
}, 0);
Scheduler API는 더 나은 제어를 위해 yield()
와 postTask()
라는 두 주요 메서드를 제공합니다. 두 메서드 중 비교적 더 간단한 yield()
는 실행을 중지할 수 있는 깔끔한 방법을 제공합니다.
// scheduler.yield()를 사용한 새로운 접근 방식
await scheduler.yield();
processNextBatch();
좀 더 복잡한 상황에서는 postTask()
가 제공하는 우선순위 기반의 스케줄링 방식을 활용할 수 있습니다.
await scheduler.postTask(() => {
processNextBatch() },
{ priority: 'background' }
);
Scheduler API는 user-blocking
, user-visible
, 그리고 background
의 세 가지 다른 우선순위 수준을 지원합니다. 작업은 먼저 우선순위에 따라, 그리고 스케줄러 대기열에 추가된 순서에 따라 실행됩니다.
enum TaskPriority {
"user-blocking",
"user-visible",
"background"
};
우선순위 수준은 브라우저가 언제, 얼마나 시급하게 작업을 처리해야 하는지 결정합니다. 각 우선순위가 의미하는 바는 다음과 같습니다.
user-blocking
: 메인 스레드를 차단하고 즉각적인 처리가 필요한 작업입니다. 예를 들어, 사용자 입력을 다루거나 UI를 업데이트하는 것이 있습니다.user-visible
: 중요하지만 user-blocking
만큼은 아닌 작업입니다. 예를 들어, 다음 화면을 위한 데이터 가져오기가 있습니다.background
: 사용자 경험에 영향을 미치지 않고 백그라운드에서 동작할 수 있는 작업입니다. 예를 들어, 에셋을 미리 로드하거나 분석을 수행하는 것이 있습니다.Scheduler API는 우선순위가 서로 다른 여러 작업을 관리하는 데 탁월하며, 중요한 작업을 먼저 완료하고 덜 중요한 작업은 연기하는 것을 보장합니다. 여러 개의 작업이 동시에 실행되면, 브라우저는 먼저 우선순위에 따라 처리하고, 그다음 대기열의 순서에 따라 처리합니다.
async function processData(data) {
const controller = new TaskController({ priority: 'background' });
try {
await scheduler.postTask(
() => heavyComputation(data),
{
signal: controller.signal,
priority: 'background'
}
);
} catch (error) {
if (error.name !== 'AbortError') {
console.error('Processing failed:', error);
}
}
}
작업들은 TaskController
를 통해 실행 중에 우선순위를 변경할 수 있습니다. 이는 작업의 중요도가 사용자 상호작용이나 시스템의 상태에 따라 변해야 할 때 유용합니다.
const controller = new TaskController({ priority: 'background' });
controller.signal.addEventListener('prioritychange', (event) => {
console.log(`Priority changed from ${event.previousPriority} to ${event.target.priority}`);
});
scheduler.postTask(
async () => {
// 백그라운드 작업으로 시작
await processInitialData();
// 필요한 경우 우선순위 업데이트
controller.setPriority('user-visible');
await processCriticalData();
},
{ signal: controller.signal }
);
Scheduler API는 TaskController
와 AbortController
를 통해 작업을 중단하는 것을 허용합니다.
// 기본적인 작업 중단
const controller = new TaskController();
scheduler.postTask(
async () => {
const response = await fetch('https://api.example.com/data');
return response.json();
},
{ signal: controller.signal }
).catch(error => {
if (error.name === 'AbortError') {
console.log('Task was aborted');
}
});
// 작업 중단하기
controller.abort();
Scheduler API를 사용하기 전에 브라우저가 이를 지원하는지 먼저 확인해보세요. 지원하지 않을 경우 setTimeout
을 폴백으로 사용할 수 있도록 래퍼(wrapper)를 생성하는 것이 좋습니다.
function createScheduler() {
if ('scheduler' in window) {
return {
async schedule(task, options = {}) {
return scheduler.postTask(task, options);
},
async yield() {
return scheduler.yield();
}
};
}
return {
async schedule(task, { delay = 0 } = {}) {
return new Promise((resolve, reject) => {
setTimeout(() => {
try {
resolve(task());
} catch (error) {
reject(error);
}
}, delay);
});
},
async yield() {
return new Promise(resolve => setTimeout(resolve, 0));
}
};
}
/*
Scheduler API를 지원하는 곳에서는 사용하면서,
여러 브라우저에서 동작을 지원할 수 있도록
이 폴백 패턴을 사용해보세요.
*/
const taskScheduler = createScheduler();
async function processData(data) {
try {
await taskScheduler.schedule(
() => heavyComputation(data),
{ priority: 'background' }
);
} catch (error) {
console.error('Processing failed:', error);
}
}
Scheduler API는 계속 개발 중이며, yield()
메서드는 현재 실험 기능입니다. 주요 브라우저에서는 핵심 기능을 구현하는 등, 브라우저 지원도 꾸준히 증가하고 있습니다. API의 디자인은 이전 버전과의 호환성을 유지하면서 향후 확장이 가능하게 되어있습니다.
이러한 작업 스케줄링의 표준화된 접근 방식은 웹 애플리케이션 성능의 중요한 진전을 의미합니다. 이를 통해 특정 구현에 의존한 편법이나 우회 방법에 의존하지 않고도 더욱 반응이 빠른 인터페이스와 리소스 활용이 가능합니다.
Scheduler API는 웹 애플리케이션 성능의 근본적인 문제를 해결합니다. 명확한 우선순위 조정 모델과 작업 중단 기능은 더욱 반응성이 뛰어난 애플리케이션을 제작하는 데 필요한 도구를 제공합니다. 브라우저 지원이 확장됨에 따라 이 API는 웹 개발 툴킷의 핵심이 될 것입니다.
좋은 정보 감사합니다!