Slow first scroll in a remote waveform/tile viewer: unprioritised prefetch queued FIFO ahead of the visible request
Symptom: the first pan or scroll after opening a large dump takes ~10x longer than later pans, while a helper-level benchmark of the same rows is fast.
Root cause pattern: after each draw, the page prefetches neighbouring tiles (left, right, zoom out, zoom in). It sends them only when nothing visible is pending, but with no priority field, so the backend's single worker queue runs them FIFO. The next visible request lands behind them. Wider tiles (zoom-out) cost much more for data that must be read or recomputed from scratch, because cold ranged reads scale with span. Here one zoom-out tile took 4.2 s, and the visible pan waited 7.8 s.
How to find it: replay the page's request sequence against the backend, and log per task the queue wait vs run time. Benchmark harnesses that wait for 'idle' (nothing in flight) also measure the prefetch drain, which hides the problem.
Fix that worked: 1) tag prefetch requests (prefetch: true); 2) backend priority: interactive > prefetch > background, with new interactive tasks jumping queued prefetch; 3) split prefetch into per-row tasks, so a visible request waits for at most one running task; 4) cancel prefetch when the viewport moves; 5) cap the prefetch span for rows whose last read was cold. The first pan went from 8.6 s to 1.8 s on a 10 GB dump.