Skip to content

Document container virtualization for VirtualizingStackPanel - #1113

Closed
gentledepp wants to merge 1 commit into
AvaloniaUI:mainfrom
gentledepp:feature/20259_virtualizingdatatemplate_master
Closed

Document container virtualization for VirtualizingStackPanel#1113
gentledepp wants to merge 1 commit into
AvaloniaUI:mainfrom
gentledepp:feature/20259_virtualizingdatatemplate_master

Conversation

@gentledepp

Copy link
Copy Markdown

Documentation for the container-level virtualization API proposed in AvaloniaUI/Avalonia#20993. Draft: do not merge before that PR lands, and the API names may still change in its review.

What this adds

docs/app-development/container-virtualization.md, a how-to page under App Development, plus a pointer to it from the UI virtualization section of performance.md and a sidebar entry.

The page covers:

  • What the opt-in changes: without it, recycling a container clears Content/ContentTemplate and the template's control tree is rebuilt; with it, containers are pooled per recycle key and the tree stays in place.
  • Both opt-in forms: EnableVirtualization="True" on a XAML DataTemplate, and RecycleKeySelector on a FuncDataTemplate.
  • How to choose a key: the key identifies the shape of the control tree the template built, not the data type. A template that branches on a property must key on that property.
  • The DataTemplates collection caveat: a template placed there does not opt in, because collection templates are not copied onto containers.
  • Mixed row kinds via an IVirtualizingDataTemplate template selector, including the rule that Build(data, existing) must return existing.
  • EnableWarmup and MinPoolSizePerKey.
  • The per-item memory the panel retains (about 44 bytes per item, roughly 4.2 MB at 100,000 items).
  • The process-wide ContainerVirtualization.IsEnabled kill switch.
  • When the opt-in pays off, and the honest negative: it does nothing measurable for cheap templates.

The caveat that most needs review

A :::danger block, because it is the one way this feature can break a working list:

Containers are not removed from the visual tree when they scroll out of view. The panel sets IsVisible to false and keeps the container in its Children collection, and with the opt-in the controls the template built stay attached to that container.

So Loaded, Unloaded, AttachedToVisualTree and DetachedFromVisualTree fire once, for the first item those controls ever displayed. They do not fire again as the container is reused, and the unload side does not fire when an item scrolls away. Any control that initializes per item on load, or releases state on unload, misbehaves: media players, map and chart controls, anything that subscribes to a service in OnAttachedToVisualTree. The page gives the two ways out, which are to move the work to DataContextChanged, or to leave that template opted out.

How the framework should treat view lifecycle events under container recycling is an open question on AvaloniaUI/Avalonia#20993. If that lands differently, this section is what changes.

Notes for the reviewer

  • Written against .claude/skills/docs-style-lint house rules: doc-type frontmatter, sentence-case headings, no em or en dashes, language tags on every fence, ## See also handoff. Self-checked, not run through the skill.
  • Every API name was verified against the source of VirtualizingStackPanel - content virtualization and advanced scroll position calculation supporting varying item sizes Avalonia#20993 rather than from memory: EnableVirtualization, MaxPoolSizePerKey, MinPoolSizePerKey, RecycleKeySelector, IVirtualizingDataTemplate.GetKey, EnableWarmup, ContainerVirtualization.IsEnabled.
  • The site was not built locally, so link and MDX validation rests on CI here.
  • The performance figures come from ComplexScrollBenchmark in the code PR: 5,000 heterogeneous rows, desktop x64, MediumRun. No mobile figures have been measured, so the page states the mobile case directionally and quotes no number for it.
  • The :::info line naming the pull request should be replaced with the release version once the API ships.

Adds a page covering the opt-in in both forms (EnableVirtualization in
XAML, RecycleKeySelector on a FuncDataTemplate), how to pick a recycle
key, warmup, the per-item memory the panel retains, and the process-wide
kill switch.

Calls out that opted-in containers stay in the visual tree and are only
hidden, so Loaded/Unloaded and AttachedToVisualTree/DetachedFromVisual-
Tree no longer fire per item.

Documents the API proposed in AvaloniaUI/Avalonia#20993.
@gentledepp
gentledepp force-pushed the feature/20259_virtualizingdatatemplate_master branch from cd57e24 to ba15900 Compare August 17, 2026 05:54
@luke-whos-here

Copy link
Copy Markdown
Contributor

Closing this as the corresponding PR in the main Avalonia repo has been closed without merging.

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.

2 participants