Throttle/coalesce streaming redraws and skip huge chunk redraws to reduce UI stalls#162
Merged
Conversation
Agent-Logs-Url: https://github.com/Shougo/ddu.vim/sessions/9c832e65-4ca3-4b34-a95e-25da8acdcced Co-authored-by: Shougo <41495+Shougo@users.noreply.github.com>
Agent-Logs-Url: https://github.com/Shougo/ddu.vim/sessions/9c832e65-4ca3-4b34-a95e-25da8acdcced Co-authored-by: Shougo <41495+Shougo@users.noreply.github.com>
Agent-Logs-Url: https://github.com/Shougo/ddu.vim/sessions/9c832e65-4ca3-4b34-a95e-25da8acdcced Co-authored-by: Shougo <41495+Shougo@users.noreply.github.com>
Copilot
AI
changed the title
[WIP] Fix UI freeze during candidate addition in ddu.vim
Throttle and coalesce redraws during streaming gather to reduce UI stalls
May 9, 2026
Owner
|
@copilot 試したみたのですが、まだ引っかかるようです。一度に 10000 くらい候補が追加されるような状態だと駄目ですね |
Agent-Logs-Url: https://github.com/Shougo/ddu.vim/sessions/c766a66b-aa43-49f9-8cd4-c3dada58e411 Co-authored-by: Shougo <41495+Shougo@users.noreply.github.com>
Contributor
Author
対応しました。 |
Copilot
AI
changed the title
Throttle and coalesce redraws during streaming gather to reduce UI stalls
Throttle/coalesce streaming redraws and skip huge chunk redraws to reduce UI stalls
May 9, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
大量候補を stream する source(
grep/file_recなど)で、chunk 到着ごとに全件再計算付き redraw が走り、UI が断続的に固まる状態でした。この変更では
denops/ddu/ddu.tsの redraw 発火を間引き・集約し、最終表示の整合性を維持したまま再計算回数を抑えます。Redraw scheduling (throttle/coalesce)
#refreshItems()の即時redraw()呼び出しを#redrawThrottled()に置換。REDRAW_THROTTLE_MS) で redraw 要求を集約し、短時間の連発を回避。mergeRedrawOptions()で合成し、既存のredraw()スケジューリングと整合する挙動に統一。Large chunk handling (follow-up)
>= 5000、REDRAW_STREAMING_CHUNK_LIMIT)は streaming 中の redraw をスキップ。Final consistency after gather
#refreshSources()終了時に pending throttled redraw を必ず flush して反映。Lifecycle safety (abort/quit/refresh)
quit()/cancelToRefresh()で pending timer/options を破棄。Tests
mergeRedrawOptions()の合成挙動テストを追加。isStreamingRedrawTarget()の境界値テスト(0 / 1 / 4999 / 5000 / 10000)を追加。Original prompt
Shougo/ddu.vim で、
grepやfile_recsource のように候補が数万件に達する場合、候補追加中に UI が一定時間フリーズする問題を修正してください。背景
候補追加中に
denops/ddu/ddu.tsの#refreshItems()から redraw が頻繁にスケジュールされ、#redrawInternal()が毎回 source 全体に対して重い再計算を行っています。結果として、大量候補の streaming 中に UI が断続的にフリ���ズします。主なボトルネック候補:
#refreshItems()が chunk 到着ごとにthis.redraw()を呼ぶ#redrawInternal()が毎回 source 全件に対して filter / sort / converter /ui.refreshItems()を実行する目的
実装方針
まずは最小かつ安全な修正として、
denops/ddu/ddu.tsの redraw を throttle / coalesce する方向を優先してください。想定される方向性:
Dduクラスに redraw 間引き用の状態を追加する#waitRedrawComplete/#scheduledRedrawOptionsと競合しないように設計する対象ファイル
denops/ddu/ddu.ts必要に応じてテストも追加してください。既存の Deno test スタイルに合わせてください。
受け入れ条件
grepやfile_recのような大量件数 source で、候補追加中の UI フリーズが明確に軽減されるThe following is the prior conversation context from the user's chat exploration (may be truncated):
User: @Shougo/ddu.vim grep, file_rec source のように候補が数万ある場合、候補を追加しているときに UI が一定時間フリーズする問題があります。この問題を解決したいです。
Assistant: 承知しました。いま変更の適用を進めるための確認待ちになっているので、承認または拒否をいただければ続行します。
User: @copilot Accepted Confirmation: Are you sure?
Assistant: 原因はかなり絞れています。
大量候補追加中に毎回
redraw()側で全件structuredClone + columns + filters + converters + ui.refreshItems()を走らせているため、数万件規模でメイン処理が長時間占有され、UI が固まっています。特に重いのはこの流れです。
#refreshItems()で新規 chunk を受け取るたびにthis.redraw(...)を投げるredraw()は最終的に#redrawInternal()を実行する#redrawInternal()では source ごとに#filterItems()を呼ぶ#filterItems()はstate.items全体をstructuredClone()して、columns / matchers / sorters / converters を毎回全件再実行するui.refreshItems({ items: allItems })で UI 全体更新する該当箇所はここです。
解決方針
一番効くのは、候補追加中の redraw を即時実行ではなく間引きすることです。
つまり、
This pull request was created from Copilot chat.