microsoft / microsoft/microsoft-ui-reactor

Future discussion: reset pooled controls on retrieve rather than on store

Open
#528 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

design proposal feature request
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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.