FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

perf: port WinUI Perf2026 optimizations by morning4coffe-dev · Pull Request #24094 · unoplatform/uno · GitHub

perf: port WinUI Perf2026 optimizations - #24094

Open
morning4coffe-dev wants to merge 22 commits into
masterfrom
dev/doti/winui-perf-parity
Open

perf: port WinUI Perf2026 optimizations#24094
morning4coffe-dev wants to merge 22 commits into
masterfrom
dev/doti/winui-perf-parity

Conversation

morning4coffe-dev commented Aug 17, 2026
edited
Loading

Copy link
Copy Markdown
Member

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

    • Simple one-way template bindings now compile to source/target DependencyProperty references.
    • Avoids allocating a Binding, RelativeSource, BindingPath, path nodes, and reflection-based target setter.
    • Complex paths/options and native WinUI retain the existing general binding fallback.
    • Handles templated-parent replacement, suspension/resume, attached DPs (as both source and target), hot reload cloning, and lazy ParentBinding API reconstruction.
  • Dependency-property store and metadata

    • Lazily creates low-use inherited-property and callback-token dictionaries.
    • Activates the previously inert dependency-property reflection cache with concurrency, negative-cache safety, ALC eviction, and hot-reload invalidation.
    • Avoids unnecessary weak-reference dereferences during owner validation.
  • Property paths

    • Replaces the per-step descriptor class hierarchy with a compact tagged value.
    • Stores the first two descriptors inline and spills only for longer paths.
    • Uses spans for parsing/indexers and removes several Substring, Split, Replace, and LINQ allocations.
    • Indexer parsing now matches the native std::iswdigit + _wtoi pair: only ASCII digits form an integer index, an empty index is 0, and an out-of-range index degrades to a string indexer instead of throwing FormatException/OverflowException out of the parser.
  • Small dependency-object collections

    • Stores 0–2 items inline using C# InlineArray.
    • Allocates a List<T> only on the third item.
    • Keeps versioned allocation-free enumeration and existing reentrancy/event semantics; as with List<T>, replacing an item through the indexer is not a structural change and does not invalidate in-flight enumerators.
    • Removes the collection's self-subscribed event delegate and lazily creates external handler state.
  • Transforms

    • Adds direct inverse point/bounds operations for immediate-use paths.
    • Avoids creating temporary MatrixTransform / inverse transform objects.
    • Preserves the public GeneralTransform.Inverse API and retained-transform scenarios.
  • WebAssembly DOM batching

    • Uses C# 13 params ReadOnlySpan<T> internally for style, attribute, and property batches.
    • Adds zero/one-item fast paths while preserving public params-array APIs and JS interop contracts.
  • Modern .NET primitives

    • Uses System.Threading.Lock for measured hot/contended private gates.
    • Freezes the immutable ARIA control-type role table.

Opt-in WinUI Perf2026 behavior

Compatibility-sensitive changes remain disabled by default and can be enabled together:

Uno.UI.FeatureConfiguration.Perf2026.EnableAll = true;

They can also be selected individually.

  • Optimized Fluent v2 control styles

    • Adds 11 portable Perf2026 style/resource variants.
    • Replaces zero-duration object-animation storyboards with VisualState.Setters.
    • Includes CommandBar, ScrollBar, Button, CheckBox, ComboBox, Slider, ToggleSwitch, AppBar and TabView-related optimizations.
    • Keeps non-convertible animations and controls without optimized variants unchanged.
  • Deferred overridden style setters

    • Losing style setters no longer materialize expensive values until they become effective.
    • Theme/static-resource setters that must register bindings remain eager.
    • The winning style is re-evaluated under its original XAML resource scope.
  • Grid-less icons

    • FontIcon and BitmapIcon can host their inner element directly.
    • Removes a transparent Grid, brush, and layout/render level per icon.
    • ImageIcon.OnApplyTemplate accepts either shape, matching upstream's adaptation in the same commit.
    • Existing visual-tree shape remains the default.

Behavior notes

  • GeneralTransform.TryTransformInverse / TryTransformBoundsInverse report false for a non-invertible transform, and callers fall back to the input coordinate. The previous code produced Point(NaN, NaN) in that case, because Matrix3x2Extensions.Inverse() ignored the Matrix3x2.Invert result. This aligns with upstream's E_FAIL contract for CTransform::TransformPoints(..., fInverse: true).
  • Perf2026Resources declares a stub InitializeComponent() for the reference assembly, which carries no XAML and therefore gets no generated code-behind. This keeps the reference and runtime API surfaces identical (validated by Uno.ReferenceImplComparer).

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.

Area Before After Change
DependencyObjectStore empty maps 168 B/object lazy up to 168 B saved per DependencyObject
Property path Name 80 B 0 B -100%
Property path First.Second 176 B 72 B -59%
Property path Items[1024] 168 B 32 B -81%
WASM single property pair 80 B 0 B -100%
WASM four property pairs 176 B 88 B -50%
Weak-reference pool gate, net10 baseline optimized 34–58% faster across 1–8 threads
Render-state gate, net10/2 threads baseline optimized 33% faster
Frozen ARIA lookups, net10 baseline optimized 34% faster
Small DO collection heap-backed immediately 2 inline slots no backing-list allocation for sizes 0–2
Immediate inverse transform temporary inverse object direct matrix inversion allocation removed
FontIcon / BitmapIcon icon + Grid + brush + child icon + child 2 objects and 1 visual level removed

Additional structural measurements:

  • Uno.UI contains 1,399 checked-in {TemplateBinding} uses; 1,391 are simple candidates for the generated DP fast path.
  • WinUI measured 82.68% of dependency-object collections at size 0–2, motivating its two-slot inline storage.
  • The Perf2026 port supplies optimized resources for 11 directly portable control groups.

For upstream context, Microsoft's File Explorer launch measurements for the WinUI portion were:

  • 41% fewer allocations
  • 63% fewer transient allocations
  • 45% fewer function calls
  • 25% less time in WinUI code

Those are upstream WinUI aggregate results and are not presented as Uno end-to-end numbers.

WinUI source references

Area Upstream reference
Overall Perf2026 results Discussion #11096
Optional compatibility-breaking perf changes XamlOptionalChanges spec
Deferred Setter.Value 0ae9b9a7
Inline CDOCollection storage f235521a
Property-path parser allocations fd139f17
Direct inverse transforms 2739fe98
TemplateBinding handler allocation bbb46616
Grid-less icons 16737fe3
Optimized built-in styles 49b4d532
CommandBar first-frame styles 55f99cde
ScrollBar resource lookups 40b0e5e1

Validation

Local (Windows, net10.0, analyzer-enabled unless noted):

  • dotnet build Uno.UI-UnitTests-only.slnf — succeeded, 0 warnings, 0 errors.
  • dotnet build Uno.UI.FluentTheme.v2.{Reference,Skia,Wasm}.csproj -c Release — succeeded, 0 warnings.
  • dotnet test --project Uno.UI.UnitTests — 4,237 passed, 23 skipped. The only failures are 12 Windows_Globalization.When_Calendar cases caused by this machine's ICU data; they pass on CI (Tests - Unit Tests stage succeeded).
  • dotnet test --project SourceGenerators/Uno.UI.SourceGenerators.Tests — 470 passed, 14 skipped, 0 failed.
  • Skia Desktop runtime tests (SamplesApp.Skia.Generic, Release net10.0) over the affected areas — icons, transforms, styles/default-style optimizations, context-requested, template-binding-adjacent controls: 506 passed, 0 failed, 4 platform skips.
  • Reference-vs-runtime API surface of Perf2026Resources compared directly from assembly metadata: identical.

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 ✅

morning4coffe-dev and others added 13 commits August 16, 2026 17:27
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
morning4coffe-dev added kind/enhancement New feature or request area/code-generation Categorizes an issue or PR as relevant to code generation area/performance 📈 Categorizes an issue or PR as relevant to performance labels Aug 17, 2026
github-actions Bot added platform/wasm 🌐 Categorizes an issue or PR as relevant to the WebAssembly platform area/skia ✏️ Categorizes an issue or PR as relevant to Skia area/automation Categorizes an issue or PR as relevant to project automation kind/documentation labels Aug 17, 2026

github-actions Bot commented Aug 17, 2026
edited
Loading

Copy link
Copy Markdown
Contributor

Claude finished @morning4coffe-dev's task in 10m 29s —— View job


PR Review: perf: port WinUI Perf2026 optimizations

Tasks

  • Load review tools
  • Review core runtime changes (BindingExpression, DependencyObjectStore, DependencyObjectCollection)
  • Review property path parser changes
  • Review style/icon/transform changes
  • Review source generator changes
  • Review XAML theme resources
  • Review test coverage
  • Post inline comments and summary

Overall Verdict: fix-first on three minor items; architecture and test coverage are excellent

The 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 Severity

Medium — 3 findings (all on the same pattern)

TryTransformInverse return value silently ignored in three call sites:

File Line
src/Uno.UI/UI/Xaml/Input/PointerRoutedEventArgs.wasm.cs 19
src/Uno.UI/UI/Xaml/Controls/Flyout/FlyoutBase.Pickers.cs 52
src/Uno.UI.Runtime.Skia.WebAssembly.Browser/Extensions/BrowserDragDropExtension.cs 361

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

  • ResourceDictionary.OverlayFrom: the if (value is LazyInitializer lazy) check inside the else branch of the theme-dictionary loop appears unreachable after the preceding TryGetValue materialisation call. Either confirm it can be reached and add a comment, or remove it.
  • BitmapIcon.cs line 66: comment says "ImageSourceConverter" but the actual mechanism is the implicit operator ImageSource?(Uri) on ImageSource. Mildly misleading — see inline comment.
  • XamlFileGenerator.cs line 4241: the attached-DP-as-target case for TemplateBinding is correctly excluded by the prefix.EndsWith(".") guard, but a generator snapshot test for that shape would lock in the expected output.

Cross-cutting Observations

TemplateBinding 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.

github-actions Bot commented Aug 25, 2026
edited
Loading

Copy link
Copy Markdown
Contributor

Claude finished @morning4coffe-dev's task in 3m 36s —— View job


PR Review: perf: port WinUI Perf2026 optimizations

Tasks

  • Load review tools
  • Review PR diff for new issues since last review
  • Check remaining gap (attached-property target snapshot test)
  • Post inline comments
  • Post summary

Overall Verdict: ship — all prior gaps closed, new commits clean

The four commits added since the second review pass cleanly address everything that was open:

Commit What it does Status
23b7b978 Adds When_TemplateBinding_Targets_Attached_Property snapshot test ✅ Closes remaining gap
8d0cd1ec ImageIcon.OnApplyTemplate handles direct Image child (Perf2026 path) ✅ Correct
86d9788a Indexer-set on DependencyObjectCollection no longer bumps _version, matching List<T> semantics ✅ Correct, tested
5a02e56c TryGetIntIndex uses (uint)(c - '0') > 9 (ASCII-only, matching std::iswdigit) and int.TryParse with NumberStyles.None instead of throwing on overflow ✅ Correct

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.

Copy link
Copy Markdown
Contributor

🤖 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

Copy link
Copy Markdown
Contributor

🤖 Your Docs stage site is ready! Visit it here: https://unodocsprstaging.z13.web.core.windows.net/pr-24094/docs/index.html

Copy link
Copy Markdown
Contributor

The build 229951 found UI Test snapshots differences: skia-linux-screenshots: 57, skia-windows-screenshots: 2348, wasm: 11

Details
  • skia-linux-screenshots: 57 changed over 2348

    🚨🚨 Comparison Details (first 20) 🚨🚨
    • Examples.png-dark
    • Examples.png
    • ExpanderColorValidationPage.png-dark
    • ExpanderColorValidationPage.png
    • Buttons.png-dark
    • Buttons.png
    • DisplayInformation.png-dark
    • ElementLevelTheme.png-dark
    • ElementLevelTheme.png
    • Focus_FocusVisual_Properties.png-dark
    • ButtonClippingTestsControl.png
    • Gamepad_CurrentReading.png-dark
    • Gamepad_CurrentReading.png
    • Gamepad_Enumeration.png-dark
    • Gamepad_Enumeration.png
    • ButtonClippingTestsControl.png-dark
    • ClipboardTests.png-dark
    • ImageIconPage.png-dark
    • ContextRequested.png-dark
    • ContextRequested.png
  • skia-windows-screenshots: 2348 changed over 2396

    🚨🚨 Comparison Details (first 20) 🚨🚨
    • ApplicationViewMode.png
    • AppWindowPositionAndSize.png-dark
    • AppWindowTitleBar Properties.png-dark
    • Attributed_text_Supserscript.png-dark
    • AutomationPropertiesExtensions_Role.png-dark
    • AutoSuggestBox_Description.png
    • BasicAutoSuggestBox.png-dark
    • Battery.png
    • BezierSegment.png
    • BindableDrawerLayout_ChangePane.png-dark
    • BorderLeftwithmargins.png-dark
    • BorderLeftwithmargins.png
    • Border_Clipped_Change_Property.png-dark
    • Border_Clipped_Change_Property.png
    • Border_Simple_with_Opacity.png
    • Border_Simple_with_Uniform_Thickness.png-dark
    • ButtonClippingTestsControl.png-dark
    • ButtonClippingTestsControl.png
    • CameraCaptureUISample.png
    • Canvas_In_Canvas.png-dark
  • wasm: 11 changed over 1076

    🚨🚨 Comparison Details (first 20) 🚨🚨
    • UITests.Windows_UI_Xaml_Media_Animation.ColorAnimation_Background
    • UITests.Microsoft_UI_Xaml_Controls.WebView2Tests.WebView2_NavigationProperties
    • UITests.Uno_Web.Http.CookieManagerTests
    • SamplesApp.Wasm.Windows_UI_Xaml_Controls.ListView.ListView_IsSelected
    • UITests.Shared.Windows_UI_Xaml_Controls.MediaPlayerElement.MediaPlayerElement_Minimal
    • UITests.Shared.Windows_UI_Xaml_Controls.MediaPlayerElement.MediaPlayerElement_Ogg_Extension
    • SamplesApp.Microsoft_UI_Xaml_Controls.WebView2Tests.WebView2_EnableDevTools
    • UITests.Windows_UI_Xaml_Controls.CalendarView.CalendarView_Theming
    • Uno.UI.Samples.Content.UITests.WebView.WebView_AnchorNavigation
    • SamplesApp.Windows_UI_Xaml_Controls.ListView.ListViewSelectedItems
    • UITests.Shared.Microsoft_UI_Xaml_Controls.ExpanderTests.WinUIExpanderPage

github-actions Bot commented Aug 25, 2026
edited
Loading

Copy link
Copy Markdown
Contributor

Claude finished @morning4coffe-dev's task in 2m 30s —— View job


PR Review: perf: port WinUI Perf2026 optimizations

Tasks

  • Load review tools
  • Review new commits since last review (d9bffdf, b0889d2, ab9bd9b)
  • Check for any new issues or regressions
  • Post inline comments
  • Post summary

Overall Verdict: ship — new commits are clean, one remaining nit

The three commits added since the third review pass are all mechanical:

Commit What it does Status
d9bffdf5 Merge master into branch ✅ Clean
b0889d23 Refresh TemplateBinding snapshot hashes after master merge (path format change altered the generator hash from d6cd… to 0e3f…) ✅ Correct mechanical refresh
ab9bd9b2 Add public void InitializeComponent() stub under #if __NETSTD_REFERENCE__ to align the reference API surface with what the XAML source generator emits for ResourceDictionary subclasses ✅ Correct — confirmed by XamlFileGenerator.cs:1899 which emits public void InitializeComponent() for ResourceDictionary types

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.

Copy link
Copy Markdown
Contributor

🤖 Your Docs stage site is ready! Visit it here: https://unodocsprstaging.z13.web.core.windows.net/pr-24094/docs/index.html

morning4coffe-dev marked this pull request as ready for review August 25, 2026 05:02
Copilot AI lite review requested due to automatic review settings August 25, 2026 05:02

github-actions Bot commented Aug 25, 2026
edited
Loading

Copy link
Copy Markdown
Contributor

Claude finished @morning4coffe-dev's task in 1m 17s —— View job


PR Review: perf: port WinUI Perf2026 optimizations

Tasks

  • Load review tools
  • Review diff for any issues since last review pass
  • Check remaining nit (redundant .ToString())
  • Post inline comments for findings
  • Post summary

Overall Verdict: ship — one cosmetic nit, no new blocking issues

This 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

Severity File Line Issue
Nit Given_MetadataAPI_DependencyPropertyCache.cs 120 Redundant .ToString() — string concatenation already calls it on integral types

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.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Pull request overview

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:

  • Introduces a generated TemplateBinding fast path and supporting store/binding infrastructure.
  • Reduces allocations across hot paths (property-path parsing, small collections/enumeration, inverse transforms, WASM DOM batching) and modernizes some synchronization/caching primitives.
  • Adds opt-in Perf2026 style + visual-tree variants (Fluent v2 optimized resource overlays, grid-less icons) and associated unit/runtime test coverage.

Reviewed 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.

Copy link
Copy Markdown
Contributor

🤖 Your Docs stage site is ready! Visit it here: https://unodocsprstaging.z13.web.core.windows.net/pr-24094/docs/index.html

Copy link
Copy Markdown
Contributor

🤖 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

Copy link
Copy Markdown
Contributor

The build 229974 found UI Test snapshots differences: skia-linux-screenshots: 57, skia-windows-screenshots: 2348, wasm: 11

Details
  • skia-linux-screenshots: 57 changed over 2348

    🚨🚨 Comparison Details (first 20) 🚨🚨
    • DisplayInformation.png-dark
    • ElementLevelTheme.png-dark
    • ElementLevelTheme.png
    • Buttons.png-dark
    • Buttons.png
    • DropDownButtonPage.png-dark
    • DropDownButtonPage.png
    • ContextRequested.png-dark
    • ContextRequested.png
    • Focus_FocusVisual_Properties.png-dark
    • Examples.png-dark
    • Examples.png
    • ExpanderColorValidationPage.png-dark
    • ExpanderColorValidationPage.png
    • ButtonClippingTestsControl.png-dark
    • ButtonClippingTestsControl.png
    • CalendarView_Theming.png-dark
    • CalendarView_Theming.png
    • Gamepad_CurrentReading.png-dark
    • Gamepad_CurrentReading.png
  • skia-windows-screenshots: 2348 changed over 2396

    🚨🚨 Comparison Details (first 20) 🚨🚨
    • AnimatedIconPage.png-dark
    • ApplicationViewMode.png
    • AppWindowPositionAndSize.png-dark
    • AppWindowTitleBar Properties.png-dark
    • Attributed_text_Simple.png-dark
    • AppBar_KeyBoard.png-dark
    • AutomationPropertiesExtensions_Role.png-dark
    • ApplicationViewSpanningRectsPage.png
    • AutoSuggestBox_BitmapIcon.png-dark
    • AutoBorderStretchwithleftmargin.png
    • BackGesture.png
    • AutoSuggestBoxChosenSuggestion.png
    • BasicThemeResources.png-dark
    • AutoSuggestBox_Reason.png-dark
    • BasicThemeResources.png
    • Basics.png
    • BorderRightwithmargins.png
    • BitmapIcon_Generic.png
    • BorderTopwithmargins.png-dark
    • BorderImageBrush.png-dark
  • wasm: 11 changed over 1076

    🚨🚨 Comparison Details (first 20) 🚨🚨
    • SamplesApp.Windows_UI_Xaml_Controls.ListView.ListViewSelectedItems
    • UITests.Microsoft_UI_Xaml_Controls.WebView2Tests.WebView2_NavigationProperties
    • UITests.Shared.Windows_UI_Xaml_Controls.MediaPlayerElement.MediaPlayerElement_Ogg_Extension
    • UITests.Windows_UI_Xaml_Controls.CalendarView.CalendarView_Theming
    • SamplesApp.Wasm.Windows_UI_Xaml_Controls.ListView.ListView_IsSelected
    • SamplesApp.Microsoft_UI_Xaml_Controls.WebView2Tests.WebView2_EnableDevTools
    • UITests.Uno_Web.Http.CookieManagerTests
    • UITests.Shared.Windows_UI_Xaml_Controls.MediaPlayerElement.MediaPlayerElement_Minimal
    • UITests.Windows_UI_Xaml_Media_Animation.ColorAnimation_Background
    • Uno.UI.Samples.Content.UITests.WebView.WebView_AnchorNavigation
    • UITests.Shared.Microsoft_UI_Xaml_Controls.ExpanderTests.WinUIExpanderPage

Copilot AI review requested due to automatic review settings August 25, 2026 08:07

github-actions Bot commented Aug 25, 2026
edited
Loading

Copy link
Copy Markdown
Contributor

Claude finished @morning4coffe-dev's task in 2m 27s —— View job


PR Review: perf: port WinUI Perf2026 optimizations

Tasks

  • Load review tools
  • Read latest commits and diff since last review
  • Investigate Copilot's TryDeferSetter precedence concern
  • Verify redundant .ToString() nit was addressed
  • Post inline comments for findings
  • Post summary

Overall Verdict: ship — last nit resolved, Copilot finding is a false positive

This is the sixth review pass. The two commits added since the fifth review are clean:

Commit What it does Status
01772542 Drops redundant .ToString() in cache concurrency test ✅ Resolves the one remaining nit from all prior reviews
ab9bd9b2 Adds InitializeComponent() stub under #if __NETSTD_REFERENCE__ to align reference API surface ✅ Already verified correct in review 4

Copilot Finding — False Positive

The 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; // defer

defers 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.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Pull request overview

Copilot reviewed 85 out of 92 changed files in this pull request and generated no new comments.

Copy link
Copy Markdown
Contributor

🤖 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

Copy link
Copy Markdown
Contributor

🤖 Your Docs stage site is ready! Visit it here: https://unodocsprstaging.z13.web.core.windows.net/pr-24094/docs/index.html

Copy link
Copy Markdown
Contributor

The build 230032 found UI Test snapshots differences: skia-linux-screenshots: 57, skia-windows-screenshots: 2348, wasm: 11

Details
  • skia-linux-screenshots: 57 changed over 2348

    🚨🚨 Comparison Details (first 20) 🚨🚨
    • DropDownButtonPage.png-dark
    • DropDownButtonPage.png
    • Focus_FocusVisual_Properties.png-dark
    • Buttons.png
    • ButtonClippingTestsControl.png-dark
    • ContextRequested.png-dark
    • ContextRequested.png
    • Examples.png-dark
    • DisplayInformation.png-dark
    • Examples.png
    • ExpanderColorValidationPage.png-dark
    • ExpanderColorValidationPage.png
    • Gamepad_CurrentReading.png-dark
    • Gamepad_CurrentReading.png
    • Gamepad_Enumeration.png-dark
    • Gamepad_Enumeration.png
    • CalendarView_Theming.png-dark
    • CalendarView_Theming.png
    • ClipboardTests.png-dark
    • ImageIconPage.png-dark
  • skia-windows-screenshots: 2348 changed over 2396

    🚨🚨 Comparison Details (first 20) 🚨🚨
    • AndroidWindowInsets.png
    • AnimatedIconPage.png
    • AppBarButtonTest.png
    • AppBarButtonWithIconTest.png
    • Accessibility_ScreenReader.png
    • AndroidWindowInsets.png-dark
    • AppBarButtonTest.png-dark
    • AppBarToggleButtonTest.png
    • ApplicationViewSizing.png
    • ApplicationViewSpanningRectsPage.png
    • AppWindowClosing.png-dark
    • AppXamlDefinedResources.png
    • Attributed_text_FontSize_Changing.png-dark
    • Attributed_text_Supserscript.png
    • ApplicationViewSpanningRectsPage.png-dark
    • AppWindowPositionAndSize.png-dark
    • AppWindowPresenters.png-dark
    • AppXamlDefinedResources.png-dark
    • ArcSegment.png-dark
    • AutoBorderStretchwithleftmargin.png
  • wasm: 11 changed over 1076

    🚨🚨 Comparison Details (first 20) 🚨🚨
    • SamplesApp.Wasm.Windows_UI_Xaml_Controls.ListView.ListView_IsSelected
    • UITests.Shared.Microsoft_UI_Xaml_Controls.ExpanderTests.WinUIExpanderPage
    • UITests.Shared.Windows_UI_Xaml_Controls.MediaPlayerElement.MediaPlayerElement_Minimal
    • UITests.Windows_UI_Xaml_Controls.CalendarView.CalendarView_Theming
    • UITests.Shared.Windows_UI_Xaml_Controls.MediaPlayerElement.MediaPlayerElement_Ogg_Extension
    • UITests.Microsoft_UI_Xaml_Controls.WebView2Tests.WebView2_NavigationProperties
    • SamplesApp.Microsoft_UI_Xaml_Controls.WebView2Tests.WebView2_EnableDevTools
    • UITests.Windows_UI_Xaml_Media_Animation.ColorAnimation_Background
    • UITests.Uno_Web.Http.CookieManagerTests
    • SamplesApp.Windows_UI_Xaml_Controls.ListView.ListViewSelectedItems
    • Uno.UI.Samples.Content.UITests.WebView.WebView_AnchorNavigation

This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/automation Categorizes an issue or PR as relevant to project automation area/code-generation Categorizes an issue or PR as relevant to code generation area/performance 📈 Categorizes an issue or PR as relevant to performance area/skia ✏️ Categorizes an issue or PR as relevant to Skia kind/documentation kind/enhancement New feature or request platform/wasm 🌐 Categorizes an issue or PR as relevant to the WebAssembly platform

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Align Uno XAML performance with WinUI Perf2026

4 participants


Back | FazBrowse Home | New Git URL