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, se libera su memoria 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 los elementos que deben estar ocultos. 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 un objeto VisualState, use una animación Setter o Storyboard que tenga como destino el elemento x:Load.
  • Establecer como destino 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, lo que podría provocar problemas de estabilidad en la interfaz de usuario si se crean demasiados al mismo tiempo.

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 del elemento.
  • Si se ha registrado para recibir notificaciones de cambio de propiedad en la propiedad que contiene los elementos aplazados, 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 un objeto Page 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 un objeto 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 objeto Page, userControl o DataTemplate.
  • No se puede usar x:Load en elementos de resourceDictionary.
  • No puedes usar x:Load en XAML dinámico 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 darse cuenta de 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 fotograma. Una buena opción para encontrar candidatos a ser aplazados es buscar elementos que se vayan a crear con Visibility 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 de aplazar elementos en una ListView, ya que disminuirá el tiempo de inicio, pero también podría reducir el rendimiento de movimiento panorámico en función de lo que esté creando. Si desea aumentar el rendimiento del movimiento panorámico, consulte la extensión de marcado {x:Bind} y la documentación del 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, incluidas las fases.

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

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);
}