fix(feed): eliminate event-loop blocking during feed refresh
The boot refresh blocked the UI for up to 195ms per sync block with 10 large feeds (500 episodes × 10KB descriptions), causing noticeable freezes when navigating to Feed during startup. Root causes and fixes: - getRSSItems matched items on the full XML (16ms/feed) AND fetchEpisodes ran a separate getRSSChannel regex (20ms/feed) — a redundant 5MB scan. Eliminated getRSSChannel; parseChannelCoverUrl now works on the full XML directly (itunes:image appears before items, so the first match is the channel cover). - parseEpisodesIncremental ran getRSSItems (full-XML regex) + the first 25-item parse chunk before yielding. Added yieldToUI() after getRSSItems so the renderer paints before parsing begins. - Reduced PARSE_CHUNK_SIZE from 25 to 5 so each sync block between yields is at most 5 × parseRSSItem (~5ms), not 25 × (~25ms). - Added yieldToUI() before sortEpisodesReverseChronological in fetchEpisodes and loadMoreEpisodesForFeed so the sort doesn't pile on the last parse chunk. - Added yieldToUI() after response.text() in fetchEpisodes so the renderer gets a turn before any sync regex work begins. Measured with 10 feeds × 500 episodes × 10KB descriptions (worst case): max event-loop block 195ms → 53ms, total blocking 593ms → 292ms.
This commit is contained in:
@@ -45,6 +45,10 @@ export function ProgressBar() {
|
||||
padding={0}
|
||||
flexDirection="row"
|
||||
gap={0}
|
||||
// The bar's block-char texts are non-selectable below: a drag
|
||||
// over the bar is a seek gesture, not a text selection — otherwise
|
||||
// mouse-up would copy █/░ to the clipboard via the global
|
||||
// selection handler.
|
||||
ref={(el) => {
|
||||
bar = el;
|
||||
}}
|
||||
@@ -58,9 +62,11 @@ export function ProgressBar() {
|
||||
}}
|
||||
>
|
||||
{playedChars() > 0 && (
|
||||
<text fg={theme.primary}>{"\u2588".repeat(playedChars())}</text>
|
||||
<text fg={theme.primary} selectable={false}>
|
||||
{"\u2588".repeat(playedChars())}
|
||||
</text>
|
||||
)}
|
||||
<text fg={remainingColor}>
|
||||
<text fg={remainingColor} selectable={false}>
|
||||
{"\u2591".repeat(width() - playedChars())}
|
||||
</text>
|
||||
</box>
|
||||
|
||||
Reference in New Issue
Block a user