Multi-diff editor retains disposed row DOM across input changes
- Dominant language
- TypeScript
- Stars
- 193k
- Forks
- 42.4k
- PR merge metrics
- PR metrics pending
Description
Does this issue occur when all extensions are disabled?: N/A — reproduced in isolated browser diagnostics with no extension host; not separately reproduced via the installed app's UI.
- VS Code Version: 1.138.0-insider, `7b7e49c83affacfac726040280da69b4999f3e01` (2026-09-11). Diagnostics used `33a6a088236067e1a16d08481d617dfcf6da2e2c`; affected code is identical.
- OS Version: macOS 26.6.2, arm64; headless Chromium diagnostics.
Steps to Reproduce:
1. In a browser harness, create a real compact `MultiDiffEditorWidget` at 900×640 with 90 two-sided text diffs using `MultiDiffEditorInput`, real model services, and a synthetic text-model resolver. Collapse all before `setViewModel`, yielding about 20 row templates.
2. Keep the widget alive. Call `setViewModel(undefined)`, dispose the input, load another 90-file input, and repeat three times. Count `.multiDiffEntry` elements after each clear.
**Observed:** retained row DOM grows **20 → 35 → 50 → 65**. Each cleared state has zero text models and only five cached templates/ten live label listeners. Disposed rows remain attached until the entire widget is disposed.
**Expected:** disposed templates remove their DOM; only the five intentionally cached templates remain after clearing.
**Cause / fix direction:** [`DiffEditorItemTemplate` appends its root](https://github.com/microsoft/vscode/blob/7b7e49c83affacfac726040280da69b4999f3e01/src/vs/editor/browser/widget/multiDiffEditor/diffEditorItemTemplate.ts#L287) but never removes it on disposal. The [pool disposes excess templates](https://github.com/microsoft/vscode/blob/7b7e49c83affacfac726040280da69b4999f3e01/src/vs/editor/browser/widget/multiDiffEditor/virtualizedItemManager.ts#L251-L293), leaving their DOM behind. Register root removal with the template's lifetime, **not** with unbinding, since pooled templates are reused. A temporary isolation experiment kept retained DOM at five across the same cycles.
Add regression coverage for DOM counts after repeated input replacement and pool eviction. This is actual DOM retention, distinct from the bounded listener-count warning in #206959.
Relevant pool/lifecycle history: https://github.com/microsoft/vscode/commit/10de1b9343662a4043258b418630481e27c863b1 (@hediet).
Contributor guide
Assessment
This issue has not been assessed yet.