Atributo x:Load

Puedes usar x:Load para optimizar el inicio, la creación de árboles visuales y el uso de memoria de la aplicación XAML. El uso de x:Load tiene un efecto visual similar a Visibility, salvo que cuando el elemento no está cargado, su memoria se libera y se usa internamente un pequeño marcador de posición para marcar su lugar en el árbol visual.

El elemento de la interfaz de usuario con atributos x:Load se puede cargar y descargar mediante código, o mediante una expresión x:Bind . Esto resulta útil para reducir los costos de los elementos que se muestran con poca frecuencia o condicionalmente. Cuando se usa x:Load en un contenedor como Grid o StackPanel, el contenedor y todos sus elementos secundarios se cargan o descargan como un grupo.

El seguimiento de elementos aplazados por el marco XAML agrega aproximadamente 600 bytes al uso de memoria de cada elemento con atributos x:Load, para tener en cuenta el marcador de posición. Por lo tanto, es posible sobreutilizar este atributo en la medida en que el rendimiento disminuya realmente. Se recomienda que solo lo use en elementos que deba ocultarse. Si usa x:Load en un contenedor, la sobrecarga solo se paga por el elemento con el atributo x:Load.

Importante

El atributo x:Load está disponible a partir de Windows 10, versión 1703 (Creators Update). Para poder usar x:Load, la versión mínima del proyecto de Visual Studio debe ser Windows 10 Creators Update (10.0, compilación 15063) .

Uso del atributo XAML

<object x:Load="True" .../>
<object x:Load="False" .../>
<object x:Load="{x:Bind Path.to.a.boolean, Mode=OneWay}" .../>

Carga de elementos

Hay varias maneras diferentes de cargar los elementos:

  • Use una expresión x:Bind para especificar el estado de carga. La expresión debe devolver true para cargar y false para descargar el elemento.
  • Llame a FindName con el nombre que definió en el elemento .
  • Llame a GetTemplateChild con el nombre que definió en el elemento.
  • En visualState, use una animación Setter o Storyboard que tenga como destino el elemento x:Load.
  • Dirija el elemento descargado en cualquier guión gráfico.

NOTA: Una vez iniciada la creación de instancias de un elemento, se crea en el subproceso de la interfaz de usuario, por lo que podría provocar que la interfaz de usuario se desconombree si se crea demasiado a la vez.

Una vez creado un elemento diferido en cualquiera de las formas enumeradas anteriormente, suceden varias cosas:

  • Se genera el evento Loaded en el elemento .
  • Se establece el campo para x:Name.
  • Se evalúan los enlaces x:Bind en el elemento.
  • Si se ha registrado para recibir notificaciones de cambio de propiedad en la propiedad que contiene los elementos diferidos, se genera la notificación.

Descargar elementos

Para descargar un elemento:

  • Use una expresión x:Bind para especificar el estado de carga. La expresión debe devolver true para cargar y false para descargar el elemento.
  • En una página o UserControl, llame a UnloadObject y pase la referencia de objeto.
  • Llame a Windows.UI.Xaml.Markup.XamlMarkupHelper.UnloadObject y pase la referencia de objeto.

Cuando se descarga un objeto, se reemplazará en el árbol por un marcador de posición. La instancia de objeto permanecerá en memoria hasta que se hayan liberado todas las referencias. La API UnloadObject en page/UserControl está diseñada para liberar las referencias que contiene codegen para x:Name y x:Bind. Si mantiene referencias adicionales en el código de la aplicación, también tendrán que liberarse.

Cuando se descarga un elemento, se descartará todo el estado asociado al elemento, por lo que si usa x:Load como una versión optimizada de Visibility, asegúrese de que todo el estado se aplica a través de enlaces o se vuelve a aplicar mediante código cuando se desencadena el evento Loaded.

Restricciones

Las restricciones para usar x:Load son:

  • Debe definir un x:Name para el elemento, ya que debe haber una manera de encontrar el elemento más adelante.
  • Solo puede usar x:Load en tipos que derivan de UIElement o FlyoutBase.
  • No se puede usar x:Load en elementos raíz de un elemento Page, un UserControl o dataTemplate.
  • No se puede usar x:Load en elementos de resourceDictionary.
  • No puedes usar x:Load en XAML flexible cargado con XamlReader.Load.
  • Al mover un elemento primario se borrarán todos los elementos que no se hayan cargado.

Comentarios

Puede usar x:Load en elementos anidados, pero deben realizarse desde el elemento más externo de .  Si intenta realizar un elemento secundario antes de que se haya realizado el elemento primario, se genera una excepción.

Normalmente, se recomienda aplazar los elementos que no se pueden ver en el primer marco. Una buena guía para buscar candidatos a aplazar es buscar elementos que se crean con visibilidad contraída. Además, la interfaz de usuario desencadenada por la interacción del usuario es un buen lugar para buscar elementos que se pueden aplazar.

Tenga cuidado con aplazar los elementos en un control ListView, ya que reducirá el tiempo de inicio, pero también podría reducir el rendimiento del movimiento panorámico en función de lo que cree. Si desea aumentar el rendimiento del movimiento panorámico, consulte la documentación sobre la extensión de marcado {x:Bind} y el atributo x:Phase.

Si el atributo x:Phase se usa junto con x:Load , cuando se realiza un elemento o un árbol de elementos, los enlaces se aplican hasta la fase actual y se incluyen. La fase especificada para x:Phase afecta o controla el estado de carga del elemento. Cuando se recicla un elemento de lista como parte del movimiento panorámico, los elementos realizados se comportarán de la misma manera que otros elementos activos y los enlaces compilados ({x:Bind} ) se procesan con las mismas reglas, incluida la fase.

Una guía general es medir el rendimiento de la aplicación antes y después para asegurarse de obtener el rendimiento que desee.

Ejemplo

<StackPanel>
    <Grid x:Name="DeferredGrid" x:Load="False">
        <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="Orange" Margin="0,0,4,4"/>
        <Rectangle Height="100" Width="100" Fill="Green" Grid.Column="1" Margin="4,0,0,4"/>
        <Rectangle Height="100" Width="100" Fill="Blue" Grid.Row="1" Margin="0,4,4,0"/>
        <Rectangle Height="100" Width="100" Fill="Gold" Grid.Row="1" Grid.Column="1" Margin="4,4,0,0"
                   x:Name="one" x:Load="{x:Bind (x:Boolean)CheckBox1.IsChecked, Mode=OneWay}"/>
        <Rectangle Height="100" Width="100" Fill="Silver" Grid.Row="1" Grid.Column="1" Margin="4,4,0,0"
                   x:Name="two" x:Load="{x:Bind Not(CheckBox1.IsChecked), Mode=OneWay}"/>
    </Grid>

    <Button Content="Load elements" Click="LoadElements_Click"/>
    <Button Content="Unload elements" Click="UnloadElements_Click"/>
    <CheckBox x:Name="CheckBox1" Content="Swap Elements" />
</StackPanel>
// This is used by the bindings between the rectangles and check box.
private bool Not(bool? value) { return !(value==true); }

private void LoadElements_Click(object sender, RoutedEventArgs e)
{
    // This will load the deferred grid, but not the nested
    // rectangles that have x:Load attributes.
    this.FindName("DeferredGrid"); 
}

private void UnloadElements_Click(object sender, RoutedEventArgs e)
{
     // This will unload the grid and all its child elements.
     this.UnloadObject(DeferredGrid);
}