| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Sorry, something went wrong.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 32465e77-b7f6-48bf-a485-bb510c840e2a
MetadataAPI's DependencyProperty reflection cache was read but never written, so every PropertyPath resolution re-reflected the owner type. Populate it, make it concurrent (property-path resolution is not UI-thread confined), and prune it through the shared ALC sweep engine on unload. Negative results are only cached when the type exposes no matching member at all, so a member whose static initializer has not run yet cannot poison the cache. Allocate DependencyObjectStore's inherited-forwarded-property and property-changed-token maps on first use instead of per store (168 bytes saved per DependencyObject that uses neither), and stop ValidatePropertyOwner from eagerly dereferencing the weak reference on every GetValue/SetValue. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 23adb955-8f56-432f-b1f3-721270dba648
Port the WinUI PropertyPathParser optimization (microsoft/microsoft-ui-xaml
fd139f17) to the DirectUI parser:
- Replace the PropertyPathStepDescriptor class hierarchy with a compact
tagged readonly struct (kind + object payload + int index), so a step no
longer costs a heap object.
- Keep the first two descriptors in an [InlineArray], mirroring the
stack_vector<PropertyPathStepDescriptor, 2> used upstream, and only grow
into a List<T> for deeper paths.
- Parse from a ReadOnlySpan<char>, reuse the source instance when a segment
spans the whole path, and parse int indexers straight from the span.
- Add non-mutating ReadOnlySpan<char> overloads to the MetadataAPI attached
property lookups (caches untouched), and drop the Split/Replace
allocations from BindingPath.GetTargetContextAndPropertyName,
BindingPath.TryPrependItem and BindingItem.Equals.
Also fixes an unterminated "(" throwing IndexOutOfRangeException instead of
ArgumentException: the scan loop conditions were transcribed in the wrong
order from the C++ source.
Measured with GC.GetAllocatedBytesForCurrentThread on net10.0/x64:
"Name" 80 -> 0 bytes, "First.Second" 176 -> 72 bytes and "Items[1024]"
168 -> 32 bytes per parse.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 23adb955-8f56-432f-b1f3-721270dba648
- WeakReferencePool._gate is a process-wide static taken on every weak
reference rent/return performed by data binding and weak events, from
any thread. NativeDispatcher._gate guards the four dispatcher queues
and the composition target registry, written from background threads
and drained on the UI thread. CompositionTarget._renderingStateGate is
the per-frame render state machine, contended every frame between the
UI thread and the native render thread.
- All three are dedicated private fields that are never exposed, never
assigned to an `object`-typed local, and never used with Monitor.Wait,
Pulse or IsEntered, so System.Threading.Lock is semantically identical
here while taking the lock-object-free fast path. Lock is reentrant
like Monitor, so the nested `lock (_renderingStateGate)` inside
EnqueueRenderCallback and the DEBUG-only AssertRenderStateMachine
re-entry keep working unchanged.
- Uno.UI targets net9.0/net10.0 only and NativeDispatcher already relies
on the .NET 9 Interlocked.Exchange(ref bool, bool) overload, so no
multi-targeting fork is needed. CompositionTarget.Rendering.skia.cs
already used Lock for _frameGate, so this only extends the existing
precedent to the remaining hot gates.
- Measured on a 16-core box with a standalone harness reproducing the
pool gate (Stack pop/push) and the render-state gate (flag flips):
net9.0 lock(object) -> lock(Lock)
pool gate, 1 thread 492.8 ms -> 454.6 ms (-7.8%)
pool gate, 2 threads 163.4 ms -> 101.9 ms (-37.6%)
pool gate, 4 threads 489.9 ms -> 242.3 ms (-50.5%)
pool gate, 8 threads 1,096.3 ms -> 769.3 ms (-29.8%)
render gate, 2 threads 319.4 ms -> 184.2 ms (-42.3%)
net10.0 lock(object) -> lock(Lock)
pool gate, 1 thread 579.1 ms -> 383.1 ms (-33.8%)
pool gate, 2 threads 247.8 ms -> 141.7 ms (-42.8%)
pool gate, 4 threads 660.7 ms -> 279.4 ms (-57.7%)
pool gate, 8 threads 1,224.8 ms -> 702.4 ms (-42.7%)
render gate, 2 threads 301.5 ms -> 203.2 ms (-32.6%)
- Add Given_WeakReferencePool_Concurrency and
Given_NativeDispatcher_Concurrency, both driving 8 threads through a
Barrier, to pin the invariants the gates exist for: pooled handles are
never handed to two callers at once, the pool never grows past
MaxReferences, rented references survive a concurrent ClearCache, and
concurrent EnqueueRender/RemoveCompositionTargets never corrupt the
registry or disturb unrelated targets.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- AriaMapper.ControlTypeToRoleMap is a 31 entry static initializer that is never added to, removed from or replaced: it holds no user configuration, takes part in no dynamic registration, and is not touched by hot reload or ALC unload, so it is a build-once/read-many table by construction. It is read once per element for every accessibility tree sync, which on Skia heads runs over the whole visual tree whenever a screen reader is attached. - FrozenDictionary pays its extra construction cost once at type init and returns a faster reader. Measured with 50M enum keyed lookups of this exact table: net9.0 621.0 ms -> 491.1 ms (-20.9%), net10.0 607.2 ms -> 399.7 ms (-34.2%). - Add Given_AriaMapper to lock the mapping down, including the control types that are deliberately absent from the table (Text, Calendar, Separator must stay role-less) so a future edit cannot silently change the a11y contract while reshaping the collection. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
DependencyObjectCollection<T> always allocated a List<T> and its backing array, even for the 0-2 item collections that dominate a XAML tree (Setters, VisualStates, Storyboard children, Inlines, Grid definitions). Inspired by the WinUI inline storage collections, items are now held in a two-slot [InlineArray] on the collection itself, and only spill to a List<T> when a third item is added. - Add a struct Enumerator with List<T>-style version checks, so GetEnumeratorFast() stays allocation-free over both the inline and the spilled storage. - Drop the self-subscription to VectorChanged that only existed to call OnCollectionChanged(): the virtual hook is now invoked directly, before the external handlers, so a collection nobody listens to no longer allocates a handler list, a delegate, or VectorChangedEventArgs. - Allocate the handlers list and its lock lazily. - Move the internal consumers of the removed 'List<T> Items' to Count / GetEnumeratorFast() / the collection itself. Compile: Uno.UI.Reference (analyzers enabled) and SamplesApp.Skia.Generic -c Release both build with 0 warnings, 0 errors. Unit: Uno.UI.UnitTests 4159 tests, 12 failures, all of them pre-existing Windows_Globalization Calendar failures also observed on the unmodified branch (4091 tests, same 12 failures). Runtime: Skia desktop runtime tests for Given_DependencyObjectCollection, Given_VisualStateManager, Given_Style, Given_Grid, Given_TextBlock, Given_Run and Given_Storyboard: 227 passed, 0 failed, 8 skipped. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 23adb955-8f56-432f-b1f3-721270dba648
Port the WinUI inverse-transform allocation reduction (microsoft-ui-xaml 2739fe98) to Uno. Add internal GeneralTransform.TryTransformInverse and TryTransformBoundsInverse virtuals; Transform overrides them to invert MatrixCore directly (Matrix3x2.Invert, with an identity short-circuit) instead of allocating the MatrixTransform that InverseCore returns. The base implementation still falls back on InverseCore, so custom GeneralTransform subclasses keep their existing behaviour. Replace the hot call sites that used TransformToVisual(...).Inverse solely for an immediate transformation: ContextRequestedEventArgs.TryGetPosition, FlyoutBase.PlaceFlyoutForDateTimePicker, Slider.MoveThumbToPoint, PointerRoutedEventArgs.ToRelativePosition (wasm) and BrowserDragDropExtension.GetPosition. Non-invertible transforms now take an explicit failure branch instead of silently propagating NaN, matching WinUI's E_FAIL handling. Thumb keeps its Inverse usage because it retains the transform across pointer moves, as WinUI does. Public GeneralTransform.Inverse and Transform.InverseCore are unchanged. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 23adb955-8f56-432f-b1f3-721270dba648
Switch the internal WASM DOM batching entry points (UIElement.SetStyle / SetAttribute / SetProperty, WindowManagerInterop.SetStyles / SetAttributes / SetProperty and the BrowserHtmlElement native helpers) to C# 13 params ReadOnlySpan<(string, string)>, so inline call sites get a stack allocated argument buffer instead of a heap allocated tuple array. Single pair batches now go straight to the scalar JS entry points, which are equivalent on the JS side, dropping the flat interop array too. Longer batches keep handing a valid string[] to the JSImport, now built by the shared HtmlPropertyPairs.Flatten helper. Public params (string, string)[] APIs (BrowserHtmlElement.SetCssStyle / SetHtmlAttribute, UIElementWasmExtensions) are untouched and forward to the span based helpers. Measured on a 4 pair batch: 176 -> 88 bytes per call (-50%); the tuple array is gone from the IL of the call sites. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Ports the portable parts of the WinUI "perf2026" default style work to Uno. The optimized dictionaries replace the visual state storyboards that only carry zero-duration DiscreteObjectKeyFrames by VisualState.Setters (which apply at the same Animations precedence), and reduce the resource lookups performed while materializing a template (ScrollBar repeat buttons now share a keyed Style instead of each assigning an inline ControlTemplate). Optimized variants are provided for AppBarButton, AppBarToggleButton, Button, CheckBox, ComboBox, CommandBar, NavigationBackButton, ScrollBar, Slider, TabView and ToggleSwitch. The feature is opt-in through the new FeatureConfiguration.Style.UseDefaultStyleOptimizations flag: when disabled (the default), the visual trees and behavior are strictly unchanged. When enabled, Perf2026Resources is overlaid onto XamlControlsResources, and styles marked with IsOptimizedStyle="True" are registered in a separate default style channel that falls back to the regular one for types without an optimized variant. Animations that cannot be expressed as a setter (non-zero KeyTime, easings, double/color animations, visual transitions) are intentionally left untouched. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 32465e77-b7f6-48bf-a485-bb510c840e2a
Port WinUI's deferred OptimizedStyle setter values (microsoft-ui-xaml 0ae9b9a7) to Uno's managed property system: a style setter whose target property already has a base value at a higher precedence is no longer applied, so its value is never built. Uno keeps a single base value slot and re-queries the winning style through ReevaluateBaseValue when that higher precedence is cleared, which makes the skip observationally equivalent while avoiding the cost of building templates and other expensive setter values that a built-in style immediately loses to an explicit or implicit style. Setters backed by a StaticResource/ThemeResource are never deferred, since applying them registers the theme and hot reload bindings that keep the value refreshed. Skipping a setter still performs the resource binding cleanup that applying it would have done, so a binding from a previously applied style cannot resurface at the skipped precedence. Style.TryGetPropertyValue now resolves setter values in the scope the Style was declared in, matching Style.ApplyTo, so a deferred value built through ReevaluateBaseValue resolves resources identically. The behavior can be disabled through FeatureConfiguration.Style.DeferOverriddenSetterValues. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 32465e77-b7f6-48bf-a485-bb510c840e2a
Port the WinUI `no extra Grid` icon optimization (microsoft-ui-xaml 16737fe3) to Uno. FontIcon and BitmapIcon now host their TextBlock/Image directly instead of wrapping it in a Grid filled with a transparent SolidColorBrush, saving two objects and one layout/render level per icon. Because the visual tree shape changes, the optimization is opt-in behind the new Uno.UI.FeatureConfiguration.Perf2026 surface via Perf2026.IconElementNoGridContainer, falling back to Perf2026.EnableAll. The value is latched per instance when the icon creates its child, so toggling it at runtime can never corrupt an already built tree. As in WinUI, only FontIcon and BitmapIcon opt in; SymbolIcon, PathIcon, ImageIcon and IconSourceElement keep the Grid. IconElement.IsViewHit() now returns true when the direct child path is used, preserving the hit-testable surface that the transparent Grid background provided. Measure and arrange are unchanged: the single child is measured against the available size and arranged in the full final rect, exactly as the Grid did. Also drop BitmapIcon's self-binding of Image.Source to UriSource in favour of a direct UriSource property-changed callback. The binding converted Uri to ImageSource through ImageSourceConverter, which simply invokes ImageSource's implicit Uri operator, so the direct cast keeps identical semantics while removing a Binding, a BindingExpression and a type-descriptor conversion per BitmapIcon. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 32465e77-b7f6-48bf-a485-bb510c840e2a
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 32465e77-b7f6-48bf-a485-bb510c840e2a
|
Claude finished @morning4coffe-dev's task in 10m 29s —— View job PR Review: perf: port WinUI Perf2026 optimizationsTasks
Overall Verdict: fix-first on three minor items; architecture and test coverage are excellentThe PR is a high-quality, well-structured port. The allocation wins are real and well-measured, the opt-in design is clean, and the test suite is thorough (unit tests for every changed hot path, new runtime tests, new generator snapshots). The findings below are all correctable before merge. Issues by SeverityMedium — 3 findings (all on the same pattern) TryTransformInverse return value silently ignored in three call sites:
In all three cases, ContextRequestedEventArgs.cs (in this same PR) correctly checks the return value and skips the transformation when the transform is not invertible. The three affected sites swapped the old NRE crash (on a null Inverse) for a silent wrong-coordinate fallback: when the transform is non-invertible, the absolute point is silently used as the relative position. Inline comments with suggested fixes have been posted on each. Low — 1 finding DependencyPropertyDetailsCollection.cs hot-reload binding clone (line 70): when DependencyProperty.GetProperty(...) returns null for a renamed/removed DP during hot reload, the fast-path template binding is silently dropped with no log. The old classic-binding path has equivalent gaps, but a Debug log here would make hot-reload binding loss diagnosable. Low / Code Clarity
Cross-cutting ObservationsTemplateBinding fast path — design is correct: the BindingExpression(sourceProperty, sourcePath) constructor calls ApplyTemplateBindingParent() immediately; deferred re-application via SetTemplatedParent2(reapplyTemplateBindings) and ApplyTemplateBindings() is correctly wired. The _subscription field is null for fast-path expressions and all access sites use ?. — no NPE risk. DependencyObjectCollection InlineArray — the Spill() transition (inline → List<T>) is one-way and correct; _spilledItems becomes sole storage and the inline slots are zeroed to avoid GC-pinned references. The lock-free lazy lock object via Interlocked.CompareExchange is sound. System.Threading.Lock — the switch from object to Lock in NativeDispatcher and WeakReferencePool is correct for .NET 9+ and benefits from the runtime's faster Lock implementation. .crossruntime.cs files correctly target both WASM and Skia where .NET 9+/10 is guaranteed. MetadataAPI reflection cache — the negative-caching logic (property is not null || member is null) is sound: a member that exists but reads back null is not cached (static initializer may not have run yet), while a truly absent member is cached as null permanently. Style.TryDeferSetter — the precedence comparison GetBaseValueSourcePrecedence(property) < precedence (falling through to return true) correctly defers a setter when an existing base value has higher priority (lower enum value). The ClearResourceBindingsForSkippedSetter call mirrors the binding-cleanup that applying the setter would have performed, preserving theme-binding correctness. BitmapIcon binding → DP callback — ImageSource has implicit operator ImageSource?(Uri) so the cast (ImageSource)uriSource is valid for both null (reset) and non-null values, and _image is not null guards construction ordering. Semantics are equivalent to the old binding. |
Sorry, something went wrong.
|
Claude finished @morning4coffe-dev's task in 3m 36s —— View job PR Review: perf: port WinUI Perf2026 optimizationsTasks
Overall Verdict: ship — all prior gaps closed, new commits cleanThe four commits added since the second review pass cleanly address everything that was open:
No new findings. No inline comments to post. Verification of the attached-property target snapshot (WhTeBiTaAtPr)The snapshot for Grid.Row="{TemplateBinding TabIndex}" confirms the fast path correctly emits: global::Uno.UI.Xaml.BindingHelper.SetTemplateBinding(
__p1,
global::Microsoft.UI.Xaml.Controls.Grid.RowProperty, // target: attached DP
global::Microsoft.UI.Xaml.Controls.Button.TabIndexProperty,
@"TabIndex");SetTemplateBinding(__p1, Grid.RowProperty, ...) is correct — SetValue(Grid.RowProperty, value) works on any DependencyObject, so the attached-property case is handled identically to a regular DP on the generated side. The snapshot locks in the expected output for future refactors. |
Sorry, something went wrong.
|
🤖 Your WebAssembly Skia Sample App stage site is ready! Visit it here: https://unowasmprstaging.z20.web.core.windows.net/pr-24094/wasm-skia-net9/index.html |
Sorry, something went wrong.
|
🤖 Your Docs stage site is ready! Visit it here: https://unodocsprstaging.z13.web.core.windows.net/pr-24094/docs/index.html |
Sorry, something went wrong.
|
The build 229951 found UI Test snapshots differences: skia-linux-screenshots: 57, skia-windows-screenshots: 2348, wasm: 11 Details
|
Sorry, something went wrong.
|
Claude finished @morning4coffe-dev's task in 2m 30s —— View job PR Review: perf: port WinUI Perf2026 optimizationsTasks
Overall Verdict: ship — new commits are clean, one remaining nitThe three commits added since the third review pass are all mechanical:
No new correctness issues found. One Remaining Nit (non-blocking)Given_MetadataAPI_DependencyPropertyCache.cs:120 — redundant .ToString() in string concatenation (CodeQL carry-over from prior review passes). Inline suggestion posted. Prior Findings — All Resolved ✅All findings from reviews 1 and 2 were resolved in 9c4e403. All gaps from review 3 were closed by 23b7b978 and 8d0cd1ec. Nothing regressed in the new commits. Screenshot diffs (57 Skia Linux, 2348 Skia Windows, 11 WASM) remain open for the author to validate visually — the high Skia Windows count is expected given the control-style and icon-layout changes in this PR, but the author should confirm baselines are acceptable before merge. |
Sorry, something went wrong.
|
🤖 Your Docs stage site is ready! Visit it here: https://unodocsprstaging.z13.web.core.windows.net/pr-24094/docs/index.html |
Sorry, something went wrong.
|
Claude finished @morning4coffe-dev's task in 1m 17s —— View job PR Review: perf: port WinUI Perf2026 optimizationsTasks
Overall Verdict: ship — one cosmetic nit, no new blocking issuesThis is the fifth review pass. The three commits added since the fourth review (d9bffdf5 merge, b0889d23 snapshot refresh, ab9bd9b2 reference API stub) are all mechanical and clean, matching the analysis in the prior review. 1 non-blocking finding
Inline suggestion posted. This has been flagged in each of the prior review passes; the one-character fix is "Absent" + (i % 64) without .ToString(). Screenshot diffs (57 Skia Linux, 2348 Skia Windows, 11 WASM) remain open for author visual validation. The high Skia Windows count is consistent with the Perf2026 control-style and icon-layout changes and is expected; the author should confirm the baselines are acceptable before merge. All prior findings from reviews 1–4 are fully resolved. No new correctness, cross-platform, or contract issues found. |
Sorry, something went wrong.
There was a problem hiding this comment.
This PR ports a broad set of WinUI “Perf2026” performance optimizations into Uno’s managed XAML runtime, spanning binding/template binding generation, dependency-property store/cache behavior, property-path parsing, transforms, DOM interop batching, and opt-in style/visual-tree changes behind FeatureConfiguration.Perf2026.
Changes:
Copilot reviewed 85 out of 92 changed files in this pull request and generated 1 comment.
Show a summary per file| File | Description |
|---|---|
| src/Uno.UI/UI/Xaml/Window/WindowManagerInterop.wasm.cs | WASM DOM batching via span |
| src/Uno.UI/UI/Xaml/Window/HtmlPropertyPairs.crossruntime.cs | Flatten helper for DOM pairs |
| src/Uno.UI/UI/Xaml/VisualStateGroup.cs | Allocation-free animation iteration |
| src/Uno.UI/UI/Xaml/UIElement.wasm.cs | Span-based DOM style/attr/property |
| src/Uno.UI/UI/Xaml/TemplatedParentScope.cs | Templated-parent update API tweak |
| src/Uno.UI/UI/Xaml/Style/Style.cs | Deferred setters + optimized styles |
| src/Uno.UI/UI/Xaml/ResourceDictionary.cs | Add overlay merge behavior |
| src/Uno.UI/UI/Xaml/Media/Transform.cs | Direct inverse transforms |
| src/Uno.UI/UI/Xaml/Media/GeneralTransform.cs | Add TryTransformInverse APIs |
| src/Uno.UI/UI/Xaml/Media/CompositionTarget.RenderScheduling.skia.cs | Use Lock for gate |
| src/Uno.UI/UI/Xaml/Media/Animation/TimelineCollection.cs | Avoid Items enumerations |
| src/Uno.UI/UI/Xaml/Input/PointerRoutedEventArgs.wasm.cs | Safer inverse transform usage |
| src/Uno.UI/UI/Xaml/Input/ContextRequestedEventArgs.cs | Safer inverse transform usage |
| src/Uno.UI/UI/Xaml/Documents/InlineCollection.cs | Enumerator type adjustment |
| src/Uno.UI/UI/Xaml/DependencyPropertyDetailsCollection.cs | Hot reload template-binding clone |
| src/Uno.UI/UI/Xaml/DependencyPropertyDetailsCollection.Bindings.cs | TemplateBinding expression support |
| src/Uno.UI/UI/Xaml/DependencyObjectStore.cs | Lazy maps + helper APIs |
| src/Uno.UI/UI/Xaml/DependencyObjectStore.Binder.cs | TemplateBinding fast-path plumbing |
| src/Uno.UI/UI/Xaml/Data/BindingHelper.cs | Generated TemplateBinding helper |
| src/Uno.UI/UI/Xaml/Controls/Slider/Slider.mux.cs | Use TryTransformInverse |
| src/Uno.UI/UI/Xaml/Controls/ImageIcon/ImageIcon.cs | Accept grid-less template shape |
| src/Uno.UI/UI/Xaml/Controls/Icons/IconElement.cs | Optional grid-less child hosting |
| src/Uno.UI/UI/Xaml/Controls/Icons/FontIcon.cs | Enable direct-child support |
| src/Uno.UI/UI/Xaml/Controls/Icons/BitmapIcon.cs | Remove binding; DP callback update |
| src/Uno.UI/UI/Xaml/Controls/Grid/RowDefinitionCollection.cs | Expose fast enumerator |
| src/Uno.UI/UI/Xaml/Controls/Grid/ColumnDefinitionCollection.cs | Expose fast enumerator |
| src/Uno.UI/UI/Xaml/Controls/Flyout/FlyoutBase.Pickers.cs | Safer inverse transform usage |
| src/Uno.UI/UI/Xaml/Controls/ContentPresenter/ContentPresenter.cs | TemplateBinding detection update |
| src/Uno.UI/RuntimeTypeMetadataUpdateHandler.cs | Clear DP reflection cache on hot reload |
| src/Uno.UI/NativeElementHosting/BrowserHtmlElement.wasm.cs | Span-based batching interop |
| src/Uno.UI/NativeElementHosting/BrowserHtmlElement.skia.cs | Span-based batching interop |
| src/Uno.UI/NativeElementHosting/BrowserHtmlElement.reference.cs | Span-based batching interop |
| src/Uno.UI/Helpers/AlcCacheSweep.cs | Generalize ALC cache sweeping |
| src/Uno.UI/FeatureConfiguration.Perf2026.IconElement.cs | Add icon no-grid flag |
| src/Uno.UI/FeatureConfiguration.Perf2026.cs | Add Perf2026 flag group |
| src/Uno.UI/FeatureConfiguration.cs | Make FeatureConfiguration partial |
| src/Uno.UI/DirectUI/PropertyPathStepDescriptor.cs | Compact tagged step descriptors |
| src/Uno.UI/DirectUI/PropertyPathParser.cs | Low-allocation path parsing |
| src/Uno.UI/DirectUI/PropertyPath.cs | Consume new descriptor storage |
| src/Uno.UI/DirectUI/MetadataAPI.cs | Concurrent DP reflection cache |
| src/Uno.UI/DataBinding/WeakReferencePool.cs | Use Lock for pool gate |
| src/Uno.UI/DataBinding/BindingPath.cs | Reduce string allocations in parsing |
| src/Uno.UI/DataBinding/BindingPath.BindingItem.cs | Faster property-name comparisons |
| src/Uno.UI/Accessibility/AriaMapper.cs | Freeze ARIA role mapping |
| src/Uno.UI.UnitTests/Windows_UI_Xaml/Given_Style.cs | Unit tests for deferred setters |
| src/Uno.UI.UnitTests/Windows_UI_Xaml/Given_MetadataAPI_DependencyPropertyCache.cs | Unit tests for DP reflection cache |
| src/Uno.UI.UnitTests/Windows_UI_Xaml/Given_HtmlPropertyPairs.cs | Unit tests for DOM pair flattening |
| src/Uno.UI.UnitTests/Windows_UI_Xaml_Data/BindingTests/Given_Binding.cs | Tests for template-binding fast path |
| src/Uno.UI.UnitTests/WeakReferencePool/Given_WeakReferencePool_Concurrency.cs | Concurrency tests for weak pool |
| src/Uno.UI.UnitTests/Dispatching/Given_NativeDispatcher_Concurrency.cs | Concurrency tests for dispatcher gate |
| src/Uno.UI.UnitTests/DependencyProperty/Given_DependencyObjectStore_LazyState.cs | Tests for lazy store dictionaries |
| src/Uno.UI.UnitTests/DependencyProperty/Given_DependencyObjectCollection.cs | Hook for collection-changed test |
| src/Uno.UI.UnitTests/BinderTests/Given_BindingPath.cs | Tests for new leaf-name parsing |
| src/Uno.UI.UnitTests/Accessibility/Given_AriaMapper.cs | Tests for frozen ARIA map |
| src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml/Given_Style.cs | Runtime tests for deferred setters |
| src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Media/Given_GeneralTransform_Inverse.cs | Runtime tests for inverse fast path |
| src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Input/Given_ContextRequested.Injection.cs | Runtime test for transformed position |
| src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Controls/Icons/Given_IconElement_NoGridContainer.cs | Runtime tests for grid-less icons |
| src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Controls/Given_Slider.cs | Runtime test for transformed press |
| src/Uno.UI.RuntimeTests/Helpers/FeatureConfigurationHelper.cs | Helper for icon no-grid flag |
| src/Uno.UI.Runtime.Skia.WebAssembly.Browser/Extensions/BrowserDragDropExtension.cs | Safer inverse transform usage |
| src/Uno.UI.FluentTheme/XamlControlsResources.cs | Overlay perf style resources |
| src/Uno.UI.FluentTheme.v2/XamlControlsResourcesV2.cs | Overlay perf style resources |
| src/Uno.UI.FluentTheme.v2/Perf2026/TabView_perf2026.xaml | New perf2026 style variant |
| src/Uno.UI.FluentTheme.v2/Perf2026/Perf2026Resources.xaml.cs | Perf2026 resources provider |
| src/Uno.UI.FluentTheme.v2/Perf2026/Perf2026Resources.xaml | Perf2026 merged dictionaries |
| src/Uno.UI.FluentTheme.v2/Perf2026/NavigationBackButton_perf2026.xaml | New perf2026 style variant |
| src/Uno.UI.FluentTheme.v2/Perf2026/Button_themeresources_perf2026.xaml | New perf2026 style variant |
| src/Uno.UI.FluentTheme.v2/FluentMerge.targets | Exclude perf2026 from merge |
| src/Uno.UI.Dispatching/Native/NativeDispatcher.cs | Use Lock for dispatcher gate |
| src/SourceGenerators/Uno.UI.SourceGenerators/XamlGenerator/XamlFileGenerator.cs | Emit template-binding fast-path code |
| src/SourceGenerators/Uno.UI.SourceGenerators.Tests/XamlCodeGeneratorTests/Out/Given_Binding/WhTeBiTaAtPr/XamlCodeGenerator_MainPage_0e3f323f9a22a3699cbcd4f0217eee4a.cs | Updated generated baseline (fast path) |
| src/SourceGenerators/Uno.UI.SourceGenerators.Tests/XamlCodeGeneratorTests/Out/Given_Binding/WhTeBiTaAtPr/XamlCodeGenerator_LocalizationResources.cs | Generated baseline update |
| src/SourceGenerators/Uno.UI.SourceGenerators.Tests/XamlCodeGeneratorTests/Out/Given_Binding/WhTeBiTaAtPr/XamlCodeGenerator_GlobalStaticResources.cs | Generated baseline update |
| src/SourceGenerators/Uno.UI.SourceGenerators.Tests/XamlCodeGeneratorTests/Out/Given_Binding/WhTeBiCaUsDePrFaPa/XamlCodeGenerator_LocalizationResources.cs | Generated baseline update |
| src/SourceGenerators/Uno.UI.SourceGenerators.Tests/XamlCodeGeneratorTests/Out/Given_Binding/WhTeBiCaUsDePrFaPa/XamlCodeGenerator_GlobalStaticResources.cs | Generated baseline update |
| src/SourceGenerators/Uno.UI.SourceGenerators.Tests/XamlCodeGeneratorTests/Given_Binding.cs | Add generator tests for fast path |
| doc/articles/feature-flags.md | Document Perf2026 + style flags |
💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.
Sorry, something went wrong.
|
🤖 Your Docs stage site is ready! Visit it here: https://unodocsprstaging.z13.web.core.windows.net/pr-24094/docs/index.html |
Sorry, something went wrong.
|
🤖 Your WebAssembly Skia Sample App stage site is ready! Visit it here: https://unowasmprstaging.z20.web.core.windows.net/pr-24094/wasm-skia-net9/index.html |
Sorry, something went wrong.
|
The build 229974 found UI Test snapshots differences: skia-linux-screenshots: 57, skia-windows-screenshots: 2348, wasm: 11 Details
|
Sorry, something went wrong.
|
Claude finished @morning4coffe-dev's task in 2m 27s —— View job PR Review: perf: port WinUI Perf2026 optimizationsTasks
Overall Verdict: ship — last nit resolved, Copilot finding is a false positiveThis is the sixth review pass. The two commits added since the fifth review are clean:
Copilot Finding — False PositiveThe Copilot comment on Style.cs:243 claims the >= comparison in TryDeferSetter is inverted. This is incorrect. In Uno's DependencyPropertyValuePrecedences enum, lower numeric values mean higher priority (Local=2, ExplicitStyle=4, DefaultValue=8). The check: if (store.GetBaseValueSourcePrecedence(property) >= precedence)
{
return false; // don't defer
}
return true; // deferdefers when GetBaseValueSourcePrecedence < precedence — i.e., when the current base value comes from a higher-priority source than the style being applied. Example: style is ExplicitStyle (4), current base is Local (2): 2 >= 4 is false → proceed to return true → defer. This is correct — Local overrides ExplicitStyle, so the style setter is wasteful to apply. The unit test When_Setter_Overridden_By_Local_Value_Then_Value_Is_Not_Materialized in Given_Style.cs verifies this behavior passes. All Prior Findings — Fully Resolved ✅Every finding from reviews 1–5 is resolved. No new correctness, contract, cross-platform, or allocation issues found in the new commits. Screenshot diffs (57 Skia Linux, 2348 Skia Windows, 11 WASM) remain open for author visual validation — the high Skia Windows count is consistent with the Perf2026 control-style and icon-layout changes; the author should confirm baselines are acceptable before merge. |
Sorry, something went wrong.
|
🤖 Your WebAssembly Skia Sample App stage site is ready! Visit it here: https://unowasmprstaging.z20.web.core.windows.net/pr-24094/wasm-skia-net9/index.html |
Sorry, something went wrong.
|
🤖 Your Docs stage site is ready! Visit it here: https://unodocsprstaging.z13.web.core.windows.net/pr-24094/docs/index.html |
Sorry, something went wrong.
|
The build 230032 found UI Test snapshots differences: skia-linux-screenshots: 57, skia-windows-screenshots: 2348, wasm: 11 Details
|
Sorry, something went wrong.
| Back | FazBrowse Home | New Git URL |
GitHub Issue: closes #24093
PR Type:
✨ Feature / 🔄 Refactoring
What changed? 🚀
This PR ports the applicable parts of WinUI 3's 2026 performance work to Uno's managed XAML runtime.
Microsoft's WinUI 3 Performance: A Leap Forward effort focuses on launch time and first-frame cost. The same patterns exist in Uno as managed allocations, reflection, collection backing stores, parser objects, temporary transforms, and unnecessary visual-tree nodes.
Runtime and generator hot paths
Generated TemplateBinding fast path
Dependency-property store and metadata
Property paths
Small dependency-object collections
Transforms
WebAssembly DOM batching
Modern .NET primitives
Opt-in WinUI Perf2026 behavior
Compatibility-sensitive changes remain disabled by default and can be enabled together:
They can also be selected individually.
Optimized Fluent v2 control styles
Deferred overridden style setters
Grid-less icons
Behavior notes
Measurements
The following are local x64 measurements from committed allocation tests or focused microbenchmarks. They measure the changed hot path, not end-to-end application startup.
Additional structural measurements:
For upstream context, Microsoft's File Explorer launch measurements for the WinUI portion were:
Those are upstream WinUI aggregate results and are not presented as Uno end-to-end numbers.
WinUI source references
Validation
Local (Windows, net10.0, analyzer-enabled unless noted):
CI: all Uno.UI - CI test stages pass — Unit Tests, Templates, WebAssembly Skia, Android Skia, Android+CoreCLR, Android+NativeAOT, iOS Skia, Desktop Skia Linux/Framebuffer/macOS/Windows, WinAppSDK, Screenshots, Add-in Version Alignment.
Screenshot comparison: skia-linux-screenshots 57, skia-windows-screenshots 2348, wasm 11. These are not produced by this PR — unrelated concurrent PRs (#24097, #24132, #24158) report the exact same three numbers against the same baseline, so the diff comes from the shared reference snapshot set, not from this branch. The Tests - Screenshots stage itself passes.
PR Checklist ✅