Rechenintensive Berechnungen oder lange Schleifen können den Hauptthread blockieren, sodass die Seite nicht mehr reagiert. Um dies zu verhindern, sollten Sie die Kontrolle regelmäßig an den Browser zurückgeben. Mit der scheduler.yield() API können Sie eine lange Aufgabe pausieren und den Browser Nutzereingaben oder das Rendering verarbeiten lassen, bevor Sie fortfahren.
Lange Aufgaben aufteilen
Verwenden Sie scheduler.yield() in asynchronen Funktionen, um die Arbeit aufzuteilen.
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;
}
}
}
Fallback-Strategien
Einige Browser unterstützen die scheduler API möglicherweise nicht. Sie MÜSSEN einen Fallback mit setTimeout implementieren, damit der Code ohne Fehler ausgeführt wird.
Fallback für 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;
}
}
}