From 36181d8dfc8fa6e35bda346b6eb3f334d0925e81 Mon Sep 17 00:00:00 2001 From: sudacode Date: Sun, 15 Mar 2026 12:22:00 -0700 Subject: [PATCH] docs: address second round of spec review feedback Add isCacheFull() method to controller interface for prefetcher stopping condition, specify pause flag mechanism for live priority, and clarify replaceChildren() applies to all subtitle root clears. --- .../2026-03-15-renderer-performance-design.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/docs/architecture/2026-03-15-renderer-performance-design.md b/docs/architecture/2026-03-15-renderer-performance-design.md index 291179d..31d8bfb 100644 --- a/docs/architecture/2026-03-15-renderer-performance-design.md +++ b/docs/architecture/2026-03-15-renderer-performance-design.md @@ -91,20 +91,21 @@ interface SubtitleCue { The prefetcher and live subtitle handler share the Yomitan parser (single-threaded IPC). Live subtitle requests must always take priority. The prefetcher: -- Pauses when a live subtitle change arrives. -- Resumes after the live subtitle has been processed and emitted. -- Yields between each background cue tokenization (e.g., via `setTimeout(0)` or checking a pause flag) so live processing is never blocked. +- Checks a `paused` flag before each cue tokenization. The live handler sets `paused = true` on subtitle change and clears it after emission. +- Yields between each background cue tokenization (via `setTimeout(0)` or equivalent) so the live handler can set the pause flag between cues. +- When paused, the prefetcher waits (polling the flag on a short interval or awaiting a resume signal) before continuing with the next cue. #### Cache Integration The prefetcher calls the same `tokenizeSubtitle` function used by live processing to produce `SubtitleData` results, then stores them into the existing `SubtitleProcessingController` tokenization cache via a new method: ```typescript -// New method on SubtitleProcessingController +// New methods on SubtitleProcessingController preCacheTokenization: (text: string, data: SubtitleData) => void; +isCacheFull: () => boolean; ``` -This uses the same `setCachedTokenization` logic internally (LRU eviction, Map-based storage). +`preCacheTokenization` uses the same `setCachedTokenization` logic internally (LRU eviction, Map-based storage). `isCacheFull` returns `true` when the cache has reached its limit, allowing the prefetcher to stop background tokenization and avoid wasteful eviction churn. #### Cache Invalidation @@ -236,7 +237,7 @@ In `renderWithTokens` (`subtitle-render.ts`), each render cycle: ```typescript const span = templateSpan.cloneNode(false) as HTMLSpanElement; ``` -3. Replace `innerHTML = ''` with `root.replaceChildren()` to avoid the HTML parser invocation on clear. +3. Replace all `innerHTML = ''` calls with `root.replaceChildren()` to avoid the HTML parser invocation on clear. This applies to `renderSubtitle` (primary subtitle root), `renderSecondarySub` (secondary subtitle root), and `renderCharacterLevel` if applicable. 4. Everything else stays the same (setting className, textContent, dataset, appending to fragment). ### Why cloneNode Over Full Node Recycling