yt-dlp fires progress hooks faster than the browser can usefully render
them. Previously every callback triggered a WebSocket emit → Vue
reactivity update → DOM re-render, causing unnecessary main-thread work
during active downloads.
Now status changes (e.g. downloading → finished) are always emitted
immediately, while progress-only updates are capped at one per 500ms
per download. A flush_pending() call at loop termination ensures the
final state is never dropped.