Skip to content

Fix continuous-scroll decode starvation and duplicate long-strip work - #107

Merged
zyk1172 merged 7 commits into
mainfrom
fix/continuous-scroll-decode-pipeline
Oct 1, 2026
Merged

zyk1172 merged 7 commits into
mainfrom
fix/continuous-scroll-decode-pipeline

Conversation

@zyk1172

@zyk1172 zyk1172 commented Oct 1, 2026

Copy link
Copy Markdown
Owner

目标

针对条漫持续下滑一段时间后,在页边界出现停顿/图片随后才出现的问题,修复当前解码与预加载管线中可以从代码直接确认的几个阻塞点。

修改

  • 连续滚动预加载不再对未知几何页面默认先解 6144px:

    • 已知本页几何时按真实比例选择 4096 / 6144 / 8192。
    • 本页未知时优先借用相邻页真实高宽比推断最终档位。
    • 连相邻几何都未知时,连续滚动预加载直接使用 8192,避免先产生 6144 缓存、随后页面进入视口又因真实比例要求 8192 而重复解码同一页。
    • 前台普通请求的未知几何默认仍保留 6144,不把最大档位扩大到所有阅读模式。
  • 把 LocalImageView/foreground 的取消真正传递到共享解码任务:

    • foreground consumer 改为逐消费者 token 计数,不再用单个 Set 标记。
    • 页面离开保留窗口、SwiftUI task 被取消时,如果没有其他前台消费者且该任务也不再属于有效 preload window,就取消对应 detached task。
    • 已经进入同步 ImageIO 的任务允许安全收尾;仍在等待 permit 的过期任务可立即退出,不继续占后续解码名额。
    • 保留 generation 防护,旧 Reader 的取消/完成不能误伤新会话同 key 任务。
  • 去掉“只要有 foreground 就冻结整个预加载队列”的全局阻塞:

    • foreground 存在时仍允许最多 1 个邻页 preload 继续推进。
    • 不允许启动第二个 preload 去占满两个 ImageIO permit,从而给可见页保留解码通道。
  • 修复 0.6 秒 debounce 在快速连续滚动中不断重置的问题:

    • 改为 leading-edge coalescing:计时器等待期间只更新到最新 preload window,不重新开始计时。
    • 连续滚动邻页解码延迟从 0.60s 降到 0.18s。
    • 分页模式继续使用 0.15s。

回归覆盖

  • 覆盖相邻条漫比例推断最终解码档位。
  • 覆盖完全未知几何时连续滚动使用 8192 fallback。
  • 锁定连续滚动 preload delay 不再回到 0.6s。
  • 覆盖 ReaderAsyncPermitPool 的排队任务取消后不会继续占用容量。

本 PR 不调整 NSCache 内存额度,也不通过扩大缓存掩盖重复解码问题。

@zyk1172
zyk1172 merged commit 1c532a1 into main Oct 1, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant