Сложные вычисления или длинные циклы могут заблокировать основной поток, из-за чего страница перестанет отвечать. Чтобы этого не происходило, нужно периодически возвращать управление браузеру. 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, чтобы код выполнялся без ошибок.
Резервное объявление для 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;
}
}
}