Desarrollo de Windows 10: rendimiento XAML
El rendimiento de las aplicaciones, como la rapidez con la que aparece su aplicación al inicio o navega para mostrar el siguiente contenido, etc. es muy importante.
El rendimiento de una aplicación puede verse afectado por muchas cosas, incluida la capacidad del motor de representación XAML para analizar todo el código XAML que tiene en su aplicación. XAML es una herramienta muy poderosa para crear UI, pero puede ser más robusta si usa las nuevas técnicas, que ahora están disponibles en aplicaciones de Windows 10.
Por ejemplo, en sus aplicaciones, hay ciertas cosas que desea mostrar cuando se carga la página y luego no las necesita. También es posible que al inicio no necesite cargar todos los elementos de la interfaz de usuario.
En las aplicaciones de Windows 10, se agregan algunas características nuevas en XAML, que mejoraron el rendimiento de XAML.
El rendimiento de cualquier aplicación universal de Windows se puede mejorar mediante las siguientes técnicas;
- Renderizado progresivo
- Carga diferida
Renderizado progresivo
En Windows 10, se introducen dos características nuevas y muy interesantes en XAML. Ellos son -
x: enlazar
Es una nueva sintaxis introducida en XAML que se usa para el enlace, que funciona casi de la misma manera que Binding la sintaxis lo hace. x:Bindtiene dos diferencias clave; proporciona validación de sintaxis en tiempo de compilación y mejor rendimiento.
X: fase
Proporciona la capacidad de priorizar la representación de controles XAML dentro de una plantilla de datos. Cada elemento de la interfaz de usuario puede tener solo una fase especificada. Si es así, se aplicará a todas las vinculaciones del elemento. Si no se especifica una fase, se asume la fase 0.
En las aplicaciones de la Plataforma universal de Windows (UWP), estas dos nuevas funciones proporcionan mejoras de rendimiento. También se puede utilizar en aplicaciones de Windows 8.x existentes que migren a Windows 10.
A continuación se muestra un ejemplo en el que los objetos de empleado están vinculados con GridView mediante el uso x:Bind palabra clave.
<Page
x:Class = "XAMLPhase.MainPage"
xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local = "using:XAMLPhase"
xmlns:d = "http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable = "d">
<Grid Background = "{ThemeResource ApplicationPageBackgroundThemeBrush}">
<GridView Name = "Presidents" ItemsSource = "{Binding}" Height = "300"
Width = "400" Margin = "50">
<GridView.ItemTemplate>
<DataTemplate x:DataType = "local:Employee">
<StackPanel Orientation = "Horizontal" Margin = "2">
<TextBlock Text = "{x:Bind Name}" Width = "95" Margin = "2" />
<TextBlock Text = "{x:Bind Title}" Width = "95" Margin = "2"
x:Phase = "1"/>
</StackPanel>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
</Grid>
</Page>
En el código XAML anterior, x:Phase = "1"se define con Título. Por tanto, en la primera fase,Name será renderizado y luego Title será renderizado.
A continuación se muestra el Employee class implementación en C #.
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using Windows.UI.Xaml.Controls;
// The Blank Page item template is documented at
http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409
namespace XAMLPhase {
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class MainPage : Page {
public MainPage() {
this.InitializeComponent();
DataContext = Employee.GetEmployees();
}
}
public class Employee : INotifyPropertyChanged {
private string name;
public string Name {
get { return name; }
set {
name = value;
RaiseProperChanged();
}
}
private string title;
public string Title {
get { return title; }
set {
title = value;
RaiseProperChanged();
}
}
public static Employee GetEmployee() {
var emp = new Employee() {
Name = "Waqas",
Title = "Software Engineer"
};
return emp;
}
public event PropertyChangedEventHandler PropertyChanged;
private void RaiseProperChanged(
[CallerMemberName] string caller = "") {
if (PropertyChanged != null) {
PropertyChanged(this, new PropertyChangedEventArgs(caller));
}
}
public static ObservableCollection<Employee> GetEmployees() {
var employees = new ObservableCollection<Employee>();
employees.Add(new Employee() { Name = "Ali", Title = "Developer" });
employees.Add(new Employee() { Name = "Ahmed", Title = "Programmer" });
employees.Add(new Employee() { Name = "Amjad", Title = "Desiner" });
employees.Add(new Employee() { Name = "Waqas", Title = "Programmer" });
employees.Add(new Employee() { Name = "Bilal", Title = "Engineer" });
employees.Add(new Employee() { Name = "Waqar", Title = "Manager" });
return employees;
}
}
}
Cuando se ejecute el código anterior, verá la siguiente ventana.
los X:Phase con x:Bind se utiliza para representar el ListView y GridView elementos de forma incremental y mejorar la experiencia de panorámica.
Carga diferida
La carga diferida es una técnica que se puede usar para minimizar el tiempo de carga de inicio al reducir la cantidad de elementos de la IU XAML al inicio de una aplicación. Si su aplicación contiene 30 elementos de la interfaz de usuario y el usuario no necesita todos estos elementos al inicio, todos esos elementos, que no son necesarios, pueden ahorrar algo de tiempo de carga al aplazar.
x:DeferLoadStrategy = "Lazy" retrasa la creación de un elemento y sus hijos, lo que reduce el tiempo de inicio pero aumenta ligeramente el uso de memoria.
El elemento diferido se puede realizar / crear llamando FindName con el nombre que se definió en el elemento.
Una vez que se crea un elemento diferido, sucederán varias cosas:
Se generará el evento Loaded en el elemento.
Se evaluarán todos los enlaces del elemento.
Si la aplicación está registrada para recibir notificaciones de cambio de propiedad en la propiedad que contiene los elementos diferidos, se generará la notificación.
A continuación se muestra un ejemplo en el que x:DeferLoadStrategy = "Lazy" se utiliza para la cuadrícula que contiene cuatro bloques de texto y no se cargará al inicio de su aplicación, hasta que la cargue.
<Page
x:Class = "UWPDeferredLoading.MainPage"
xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local = "using:UWPDeferredLoading"
xmlns:d = "http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable = "d">
<Grid Background = "{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid x:Name = "DeferredGrid" x:DeferLoadStrategy = "Lazy" Margin = "50">
<Grid.RowDefinitions>
<RowDefinition Height = "Auto" />
<RowDefinition Height = "Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width = "Auto" />
<ColumnDefinition Width = "Auto" />
</Grid.ColumnDefinitions>
<TextBlock Height = "100" Width = "100" Text = "TextBlock 1" Margin = "0,0,4,4" />
<TextBlock Height = "100" Width = "100" Text = "TextBlock 2"
Grid.Column = "1" Margin = "4,0,0,4" />
<TextBlock Height = "100" Width = "100" Text = "TextBlock 3"
Grid.Row = "1" Margin = "0,4,4,0" />
<TextBlock Height = "100" Width = "100" Text = "TextBlock 4"
Grid.Row = "1" Grid.Column = "1" Margin = "4,4,0,0" />
</Grid>
<Button x:Name = "RealizeElements" Content = "Show Elements"
Click = "RealizeElements_Click" Margin = "50"/>
</Grid>
</Page>
El siguiente programa es la implementación del evento de clic, en el que la cuadrícula se carga en la página principal de la aplicación.
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
// The Blank Page item template is documented at
http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409
namespace UWPDeferredLoading {
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class MainPage : Page {
public MainPage() {
this.InitializeComponent();
}
private void RealizeElements_Click(object sender, RoutedEventArgs e) {
this.FindName("DeferredGrid"); // This will realize the deferred grid
}
}
}
Cuando el código anterior se cumpla y se ejecute, solo verá un botón. losTextblocks no se cargan al inicio.
Ahora, cuando haces clic en el Show Elements , cargará los bloques de texto, lo que mejorará el rendimiento de inicio de su aplicación.