The issue: Every switch between projects in the sidebar freezes the web app – clicks and scrolling don't respond until it finishes. Opening a task inside the same project is smooth; switching projects is not.
Environment:
- Quire web build
b1862(service worker cachesw-quire-cache-b1862-07-24) - Chromium 152 (Electron-based desktop browser), Windows 10 x64, 16 logical cores, 1024×768 viewport, devicePixelRatio 1
- Organization with 37 projects; measured projects have ~100–250 open tasks; 4–5k DOM nodes after a switch
- Navigation via the sidebar project links (
/w/<project>?view=latest, which also opens the last viewed task)
Measurements (Oct 31, 2026):
Main-thread blocking was sampled with a MessageChannel ping loop (gaps > 50 ms), cross-checked with Long Tasks and Long Animation Frames (LoAF) observers.
| Switch to | Blocking within ~4 s | Longest single freeze |
|---|---|---|
| Large project A (1st visit) | 4.2 s | 1.3 s |
| Project B | 2.4 s | 0.7 s |
| Project C | 4.1 s | 1.5 s |
| Project D | 3.0 s | 1.4 s |
| Back to project A (visited a minute earlier) | 3.0–4.1 s | 0.9–1.3 s |
- No caching benefit: returning to a project opened a minute earlier is just as slow.
- Switching quickly (every ~4 s) queues the work: single freezes reach 2–4.3 s, the URL lags behind the clicks, and the JS heap grows from ~65 MB to ~170 MB.
- Opening a task inside the same project: no long tasks, no blocking.
- Full page reload: DOMContentLoaded ~1.6 s, load event ~3.5 s.
Where the time goes (LoAF script attribution, all in workspace.dart.js):
IDBRequest.onsuccesshandler: ~595–600 ms per switchTimerHandler:setTimeoutcallbacks: 450–920 ms (one frame was 917 ms)- First use only:
SCRIPT[src=…/workspace.dart.js_158.part.js].onload: ~880 ms (deferred part, 281 KB) - A typical switch has 6–11 long tasks totalling 1.5–3 s.
The network is not the bottleneck: 2–7 HTTP requests per switch, each under 40 ms. The data appears to come from the websocket and the local IndexedDB cache (dcache store, ~7.8k records, ~11 MB). The time is spent in client-side processing and rendering.
Additional finding: opaque responses inflate storage to over 1 GB.
navigator.storage.estimate() reports ~1,064 MB used by quire.io, of which 1,053 MB is Cache Storage. The sw-cors-cache cache holds 134 entries, and 126 of them are opaque responses from quire.s3.amazonaws.com (avatars and images). Chromium pads every opaque response by several MB for quota accounting, so a few hundred KB of real images count as about 1 GB. This can trigger quota pressure or storage eviction (including the IndexedDB cache) on devices with less disk space.
Possible fix: fetch S3 images with mode: 'cors' (with the matching CORS header on the bucket), or don't put opaque responses into Cache Storage.
Steps to reproduce:
- Open an organization with several larger projects.
- Click project A in the sidebar, then project B, then A again.
- Try to scroll or click right after each switch – the page doesn't respond for about a second.
- Optional: in DevTools → Performance, record one switch to see the long tasks listed above. Application → Storage shows the ~1 GB Cache Storage usage.
Expected:
- Switching to an already loaded project is near-instant (for example by keeping the rendered project or its parsed data in memory), and the work is split so input isn't blocked for more than ~50–100 ms.
- Cache Storage usage reflects the real size of cached files.
Related: #5074 (similar report from 2021).
I am using: Web