Attributo x:DeferLoadStrategy

Importante

A partire da Windows 10, versione 1703 (Creators Update), x:DeferLoadStrategy è sostituito dall'attributo x:Load. L'uso di x:Load="False" equivale a x:DeferLoadStrategy="Lazy", ma consente di scaricare l'interfaccia utente se necessario. Per altre informazioni, vedere l'attributo x:Load.

È possibile usare x:DeferLoadStrategy="Lazy" per ottimizzare le prestazioni di creazione della struttura o dell'avvio dell'app XAML. Quando si usa x:DeferLoadStrategy="Lazy",, la creazione di un elemento e dei relativi elementi figlio viene ritardata, riducendo i costi di memoria e il tempo di avvio. Questo è utile per ridurre i costi degli elementi visualizzati raramente o in modo condizionale. L'elemento verrà realizzato quando si fa riferimento a esso nel codice o in VisualStateManager.

Tuttavia, il rilevamento di elementi differiti dal framework XAML aggiunge circa 600 byte all'utilizzo della memoria per ogni elemento interessato. Più grande è la struttura degli elementi differiti, maggiore è il tempo di avvio che si salverà, ma a costo di un footprint di memoria maggiore. Pertanto, è possibile usare questo attributo finché le prestazioni non diminuiscono.

Utilizzo attributo XAML

<object x:DeferLoadStrategy="Lazy" .../>

Osservazioni:

Le limitazioni all'uso di x:DeferLoadStrategy sono:

  • È necessario definire un valore x:Name per l'elemento, perché deve esserci un modo per trovare l'elemento in un secondo momento.
  • È possibile differire solo i tipi che derivano da UIElement o FlyoutBase.
  • Non è possibile differire elementi radice in un elemento Page, UserControl o DataTemplate.
  • Non è possibile differire elementi in ResourceDictionary.
  • Non è possibile differire XAML separato caricato con XamlReader.Load.
  • Lo spostamento di un elemento padre cancella tutti gli elementi che non sono stati realizzati.

Esistono diversi modi per realizzare gli elementi differiti:

  • Chiamare FindName con il nome definito nell'elemento.
  • Chiamare GetTemplateChild con il nome definito nell'elemento.
  • In un elemento VisualState, usare un'animazione Setter o Storyboard che punta all'elemento differito.
  • Specificare come destinazione l'elemento differito in qualsiasi Storyboard.
  • Usare un'associazione destinata all'elemento posticipato.

NOTA: dopo essere stata avviata, la creazione dell'istanza di un elemento avviene nel thread dell'interfaccia utente, con , causando stuttering se vengono creati troppi elementi.

Dopo che un elemento differito è stato creato in uno dei modi elencati in precedenza, si verifica quanto segue:

  • Viene generato l'evento Loaded sull'elemento.
  • Tutti i binding sull'elemento vengono valutati.
  • Se è stata effettuata la registrazione per ricevere notifiche di modifica sulla proprietà contenente gli elementi posticipati, viene generata la notifica.

È possibile annidare gli elementi posticipati, tuttavia devono essere realizzati dall'elemento più esterno.  Se si tenta di realizzare un elemento figlio prima dell'elemento padre, viene generata un'eccezione.

In genere, è consigliabile posticipare gli elementi sono visualizzabili nel primo frame. Una buona linea guida per trovare candidati da posticipare consiste nel cercare gli elementi creati con l'elemento Visibility compresso. Inoltre, l'interfaccia utente attivata dall'interazione utente è un buon posto per cercare gli elementi che è possibile posticipare.

Fare attenzione a posticipare gli elementi in un elemento ListView, in quanto questo comporta la diminuzione del tempo di avvio, ma potrebbe anche ridurre le prestazioni di panoramica a seconda di quanto si intende creare. Per migliorare le prestazioni di panoramica, vedere la documentazione relativa all'estensione di markup {x:Bind} e all'attributo x:Phase.

Se l'attributo x:Phase viene usato in combinazione con x:DeferLoadStrategy, quando viene realizzato un elemento o una struttura di elementi, vengono applicati binding fino alla fase corrente. La fase specificata per x:Phase non influisce né controlla il posticipo dell'elemento. Quando un elemento elenco viene riciclato durante la panoramica, gli elementi realizzati si comportano come gli altri elementi attivi e i binding compilati (binding {x:Bind}) vengono elaborati usando le stesse regole, inclusa la suddivisione in fasi.

Una linea guida generale consiste nel misurare le prestazioni dell'app prima e dopo per assicurarsi di ottenere le prestazioni desiderate.

Esempio

<Grid x:Name="DeferredGrid" x:DeferLoadStrategy="Lazy">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition Width="Auto" />
    </Grid.ColumnDefinitions>

    <Rectangle Height="100" Width="100" Fill="#F65314" Margin="0,0,4,4" />
    <Rectangle Height="100" Width="100" Fill="#7CBB00" Grid.Column="1" Margin="4,0,0,4" />
    <Rectangle Height="100" Width="100" Fill="#00A1F1" Grid.Row="1" Margin="0,4,4,0" />
    <Rectangle Height="100" Width="100" Fill="#FFBB00" Grid.Row="1" Grid.Column="1" Margin="4,4,0,0" />
</Grid>
<Button x:Name="RealizeElements" Content="Realize Elements" Click="RealizeElements_Click"/>
private void RealizeElements_Click(object sender, RoutedEventArgs e)
{
    // This will realize the deferred grid.
    this.FindName("DeferredGrid");
}