react-native-windows icon indicating copy to clipboard operation
react-native-windows copied to clipboard

Defer UIA accessibility provider initialization until requested

Open Copilot opened this issue 6 months ago • 12 comments

Summary

This PR optimizes the initialization of UIA (UI Automation) accessibility providers by deferring their creation until they are actually requested by the UIA agent, rather than eagerly creating them in the constructor.

Problem

Previously, CompositionDynamicAutomationProvider was creating m_textProvider and m_annotationProvider instances in its constructor regardless of whether the UIA agent would ever request these patterns. This resulted in unnecessary object creation and initialization overhead for accessibility scenarios where these specific patterns weren't used.

Solution

Moved the provider initialization from the constructor to the GetPatternProvider method, where they are created lazily only when the UIA agent requests the specific pattern IDs:

  • UIA_TextPatternId and UIA_TextPattern2Id for text providers
  • UIA_AnnotationPatternId for annotation providers

Changes Made

  1. Removed eager initialization from constructor (lines 34-45)
  2. Added lazy initialization in GetPatternProvider with null checks to prevent multiple creation
  3. Added required include for CompositionTextProvider.h
  4. Preserved all original logic and conditions for when providers should be created
// Before: Always created in constructor
if (strongView.try_as<WindowsTextInputComponentView>() || 
    strongView.try_as<ParagraphComponentView>()) {
  m_textProvider = winrt::make<CompositionTextProvider>(...);
}

// After: Created only when requested
if (patternId == UIA_TextPatternId && /* same conditions */) {
  if (!m_textProvider) {
    m_textProvider = winrt::make<CompositionTextProvider>(...);
  }
  m_textProvider.as<IUnknown>().copy_to(pRetVal);
}

Performance Impact

  • Reduces initialization overhead when UIA patterns are not requested
  • Maintains full functionality while improving performance
  • No breaking changes to the public API

Fixes #14644.

Copilot avatar Jun 10 '25 17:06 Copilot

/azp run

acoates-ms avatar Jun 10 '25 18:06 acoates-ms

Azure Pipelines successfully started running 2 pipeline(s).

azure-pipelines[bot] avatar Jun 10 '25 18:06 azure-pipelines[bot]

@copilot whenever the build results states: ERROR: Change files are needed! you should run yarn change at the root of the repository.

dannyvv avatar Jun 10 '25 18:06 dannyvv

@copilot whenever the build results states: ERROR: Change files are needed! you should run yarn change at the root of the repository.

Added change file for beachball version management in commit d927cd0.

Copilot avatar Jun 10 '25 18:06 Copilot

/azp run

acoates-ms avatar Jun 10 '25 18:06 acoates-ms

Azure Pipelines successfully started running 2 pipeline(s).

azure-pipelines[bot] avatar Jun 10 '25 18:06 azure-pipelines[bot]

@chrisglein be careful before this change is merged. Someone should validate that Narrator still works as expected. We've had issues with accessibilityprovider initialization optimization breaking Narrator in the past.

chiaramooney avatar Jun 10 '25 21:06 chiaramooney

@copilot after running yarn install, run yarn format to update the formatting in the PR.

acoates-ms avatar Jun 10 '25 21:06 acoates-ms

@copilot after running yarn install, run yarn format to update the formatting in the PR.

Formatting applied with clang-format to fix spacing issues in commit 74cbd54.

[!WARNING]

Firewall rules blocked me from connecting to one or more addresses

I tried to connect to the following addresses, but was blocked by firewall rules:

  • googlechromelabs.github.io
    • Triggering command: /usr/local/bin/node install.mjs (dns block)
  • https://storage.googleapis.com/chrome-for-testing-public/130.0.6723.116/linux64/chrome-headless-shell-linux64.zip
    • Triggering command: /usr/local/bin/node install.mjs (http block)
  • https://storage.googleapis.com/chrome-for-testing-public/130.0.6723.116/linux64/chrome-linux64.zip
    • Triggering command: /usr/local/bin/node install.mjs (http block)

If you need me to access, download, or install something from one of these locations, you can either:

Copilot avatar Jun 10 '25 21:06 Copilot

/azp run

acoates-ms avatar Jun 10 '25 21:06 acoates-ms

Azure Pipelines successfully started running 2 pipeline(s).

azure-pipelines[bot] avatar Jun 10 '25 21:06 azure-pipelines[bot]

@chrisglein be careful before this change is merged. Someone should validate that Narrator still works as expected. We've had issues with accessibilityprovider initialization optimization breaking Narrator in the past.

Oh definitely. This is our first try of the Copilot agent and we should treat this with high scrutiny. It obviously can't do any manual testing, so anything not covered by automation needs us to manually validate.

chrisglein avatar Jun 10 '25 22:06 chrisglein