Memory, leaks, and scale
| Scale | List size | Guarantee |
|---|---|---|
| Small | 200 | Cheap notify; per-item Add is acceptable |
| Mid | 5,000 | AddRange → one Reset |
| Large | 50,000 | Same batching; UI must virtualize (ItemsRepeater / ListView virtualization) |
App data is not framework overhead. A 50,000-row product list occupies whatever the Product objects occupy. The framework is responsible for PropertyChanged allocations, CollectionChanged fan-out, whether popped ViewModels are collectable, and whether messengers and commands pin graphs.
- ViewModel never holds Window or Frame. Lifecycle is a Loaded / Unloaded attached property that unsubscribes on Unloaded.
- MessageHub default subscribe is weak. The handler must use the recipient argument.
- Commands are instance fields of the ViewModel and die with it. CanExecuteChanged is a weak event so a popped Button does not stay pinned.
- Dispose cancels in-flight AsyncModelCommand work.
- SetProperty equality-exits without allocating a new PropertyChangedEventArgs. PropertyChanged hops to IMainThread when a dispatcher is present.
dotnet test tests/Plugin.Uno.MVVMExpress.Core.Tests