perf(sync): add event loop yielding in archive operation handler

Add event loop yielding after hasTask() calls to prevent UI freezes
during bulk archive sync operations.

Root cause: TaskArchiveService.hasTask() loads the entire archive
(archiveYoung + archiveOld) from IndexedDB synchronously. When called
multiple times in sequence (e.g., during remote sync), this blocks the
main thread and causes browser freezes.

Changes:
- _handleUpdateTask: Add yield after hasTask() check
- _handleUpdateTasks: Convert Promise.all to sequential with yields

This fixes 12 out of 13 WebDAV archive sync E2E tests (92% pass rate).

Related changes:
- Commit 8c4daadcc: Parallelized archive task existence checks
- Commit 70946927a: Disabled worklog refresh effect
This commit is contained in:
Johannes Millan 2026-01-20 20:12:00 +01:00
parent 90bdfe54e1
commit b59aa6b8f7

View file

@ -241,6 +241,10 @@ export class ArchiveOperationHandler {
return;
}
// Yield after hasTask() check to prevent blocking the main thread
// hasTask() loads the entire archive from IndexedDB
await new Promise((resolve) => setTimeout(resolve, 0));
await taskArchiveService.updateTask(id as string, changes, {
isSkipDispatch: true,
isIgnoreDBLock: true,
@ -263,10 +267,15 @@ export class ArchiveOperationHandler {
const taskArchiveService = this._getTaskArchiveService();
// Filter to only tasks that exist in archive
// Check all tasks in parallel for better performance
const hasTaskResults = await Promise.all(
taskUpdates.map((update) => taskArchiveService.hasTask(update.id as string)),
);
// Check tasks sequentially with yielding to prevent UI freeze.
// Each hasTask() call loads the entire archive from IndexedDB, so we must
// yield between checks to prevent blocking the main thread.
const hasTaskResults: boolean[] = [];
for (const update of taskUpdates) {
hasTaskResults.push(await taskArchiveService.hasTask(update.id as string));
// Yield to event loop after each check to prevent blocking
await new Promise((resolve) => setTimeout(resolve, 0));
}
const archiveUpdates: Update<Task>[] = taskUpdates.filter(
(_, i) => hasTaskResults[i],