microsoft / microsoft/microsoft-ui-reactor
Future discussion: reset pooled controls on retrieve rather than on store
Nobody has claimed this yet.
- Dominant language
- C#
- Stars
- 646
- Forks
- 54
- Avg merge
- 1d 3h
- Merged PRs (30d)
- 84
Description
## Status: discussion / future consideration
This is **not a concrete request** — it's a design conversation worth having, but it's not clear we should actually do it. Filing it so the idea isn't lost.
## Background
Today, `ElementPool.CleanElement` resets pooled controls **on store** (return to pool). It clears value DPs (`TextBox.Text`, `ToggleSwitch.IsOn`, etc. — now via `ClearValue` per spec 050 Phase 7), visual states (`VisualStateManager.GoToState(..., ""Normal"")`), layout DPs, accessibility props, and `FlowDirection`/theme. Event subscription wiring is already lazy-on-rent via the `PoolableWireFlags` CWT.
Spec 050's `Optional` work shifts the calculus: each `PropEntry` now encapsulates ""this prop, this DP, write-or-clear based on Optional gate."" Mount could theoretically own the full DP starting state, making reset-on-store redundant for value-bearing DPs.
## Proposed model
**Today:**
```
Unmount → CleanElement (eager DP reset) → pool
Rent → ""clean"" control → Mount (writes only if value differs)
```
**Proposed:**
```
Unmount → straight to pool (no DP reset)
Rent → ""dirty"" control → Mount: each PropEntry Set(value) or ClearValue(dp) based on Optional state
```
Mount becomes a complete declarative reconcile; pool becomes a pure detached-control cache.
## Pros
- Lazy work — never-re-rented pool entries don't pay reset cost.
- Precise reset — only DPs the new mount touches; no ""reset everything just in case.""
- Single source of truth — Mount fully owns starting state, removing the leaky split between `CleanElement` + Mount.
- Closer to React's mental model (VDOM is authority; underlying primitive is just storage).
- Smaller `CleanElement` — non-DP residue (visual state, focus, animations) only.
## Cons / why it's not obviously a win
- **API asymmetry:** controlled entries today don't take a `dp:` parameter (only the new `OneWayClearValuePropEntry` does). For Mount to `ClearValue`, all controlled entries would need it too — a breaking API change comparable in surface area to spec 050 itself.
- **Event trampoline ordering:** trampolines persist across pool rent (KD-3 invariant) and read the element tag. Reset-on-rent that writes a DP before tag update could fire trampolines against the OLD element tag. Solvable, but a real ordering constraint to design around.
- **Idle memory pressure:** pool holds strong refs (Brush, content) until next rent. Today's reset-on-store releases eagerly. Long-lived pools with rarely-rented entries leak more under the proposed model.
- **Perceived latency shift:** reset-on-store is currently hidden inside unmount work (often batched, off-frame). Reset-on-retrieve front-loads it into the next mount — the user-perceived interaction path. Probably a wash for typical apps, but measurable for ""instant pop"" scenarios.
- **Non-DP residue still exists:** visual state, focus state, animation state aren't simple DPs. `CleanElement` still has to handle them. The resulting hybrid model (reset-on-retrieve for DPs, reset-on-store for everything else) may be harder to reason about than either pure model.
- **Test re-validation cost:** every pool-related selftest fixture (including the spec 050 ones — `ElementPoolOptionalResetFixture`, etc.) would need new versions under different semantics.
## Recommendation (preliminary)
Two pieces of work should land before considering this seriously:
1. **Phase 7.4 from spec 050 task doc:** expand `PoolableTypes` to admit more interactive controls (Slider, ComboBox, etc.) now that `ClearValue` semantics are uniform. This is the immediate practical win from Optional + ClearValue. No API change required. ([spec 050 task doc §7.4](https://github.com/microsoft/microsoft-ui-reactor/blob/main/docs/specs/tasks/050-controlled-prop-authority-and-optional-t-implementation.md))
2. **Audit `CleanElement` for ""what is DP value vs visual/focus/animation state"":** quantify how much becomes vestigial under reset-on-retrieve. If ~90% is value DPs, the hybrid model is acceptable. If ~50% is non-DP state, hybrid is too messy and the redesign value drops considerably.
After both, the cost/benefit becomes clearer.
## The deeper question this teases out
**Is the pool a ""cache of reset controls"" or a ""cache of detached-but-stateful controls""?**
Today it's the former. Optional opens the door to the latter, which is closer to how React's reconciler naturally expresses it. Whichever stance we take should be a deliberate decision documented in a spec — not just an emergent property of how `CleanElement` happens to work today.
## Cross-references
- Spec 050: `docs/specs/050-controlled-prop-authority-and-optional-t.md`
- Spec 050 Phase 7 `ClearValue` change: PR #525
- Origin of this discussion: PR #525 conversation with @codemonkeychris (2026-06-04 ~18:57)
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with ElementPool.CleanElement and the referenced docs/specs/050-controlled-prop-authority-and-optional-t.md, then review the Phase 7 ClearValue changes from PR #525. The issue has no implementation target yet; completion would require an agreed design or spec decision after the PoolableTypes expansion and CleanElement audit.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp
- Domain
- desktop
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100