Windows 10 Dev - Desempenho XAML

O desempenho dos aplicativos, como a rapidez com que seu aplicativo aparece na inicialização ou navega para mostrar o próximo conteúdo, etc., é muito importante.

O desempenho de um aplicativo pode ser afetado por muitas coisas, incluindo a capacidade do mecanismo de renderização XAML de analisar todo o código XAML que você tem em seu aplicativo. XAML é uma ferramenta muito poderosa para criar interface do usuário, mas pode ser mais robusta usando as novas técnicas, que agora estão disponíveis em aplicativos do Windows 10.

Por exemplo, em seus aplicativos, há certas coisas que você deseja mostrar quando a página é carregada e não precisa disso mais tarde. Também é possível que, na inicialização, você não precise que todos os elementos da IU sejam carregados.

Nos aplicativos do Windows 10, alguns novos recursos são adicionados ao XAML, o que melhorou o desempenho do XAML.

O desempenho de qualquer aplicativo Universal do Windows pode ser melhorado pelas seguintes técnicas;

  • Renderização Progressiva
  • Carregamento Adiado

Renderização Progressiva

No Windows 10, dois recursos novos e muito interessantes são introduzidos no XAML. Eles são -

x: Ligar

É uma nova sintaxe introduzida em XAML usada para vinculação, que funciona quase da mesma maneira que o Binding sintaxe sim. x:Bindtem duas diferenças principais; ele fornece validação de sintaxe em tempo de compilação e melhor desempenho.

X: Fase

Ele fornece a capacidade de priorizar a renderização de controles XAML em um modelo de dados. Cada elemento da IU pode ter apenas uma fase especificada. Nesse caso, isso se aplicará a todas as ligações no elemento. Se uma fase não for especificada, a fase 0 será assumida.

Em aplicativos da Plataforma Universal do Windows (UWP), esses dois novos recursos fornecem melhorias de desempenho. Ele também pode ser usado em aplicativos existentes do Windows 8.x que migram para o Windows 10.

Dada a seguir é um exemplo em que os objetos de funcionários são vinculados com GridView usando x:Bind palavra-chave.

<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>

No código XAML acima, x:Phase = "1"é definido com Título. Portanto, na primeira fase,Name será renderizado e então Title será processado.

Dado abaixo é o Employee class implementação em 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; 
      } 
		
   }
	
}

Quando o código fornecido acima for executado, você verá a seguinte janela.

o X:Phase com x:Bind é usado para renderizar o ListView e GridView itens de forma incremental e melhorar a experiência de panning.

Carregamento Adiado

O carregamento adiado é uma técnica que pode ser usada para minimizar o tempo de carregamento de inicialização, reduzindo o número de elementos de interface do usuário XAML na inicialização de um aplicativo. Se seu aplicativo contém 30 elementos de interface do usuário e o usuário não precisa de todos esses elementos na inicialização, todos esses elementos, que não são necessários, podem economizar algum tempo de carregamento adiando.

x:DeferLoadStrategy = "Lazy" atrasa a criação de um elemento e seus filhos, o que diminui o tempo de inicialização, mas aumenta um pouco o uso de memória.

O elemento adiado pode ser realizado / criado por Calling FindName com o nome que foi definido no elemento.

Depois que um elemento adiado é criado, várias coisas acontecerão -

  • O evento Loaded no elemento será gerado.

  • Quaisquer ligações no elemento serão avaliadas.

  • Se o aplicativo estiver registrado para receber notificações de alteração de propriedade na propriedade que contém o (s) elemento (s) adiado (s), a notificação será gerada.

A seguir está um exemplo em que x:DeferLoadStrategy = "Lazy" é usado para grade que contém quatro blocos de texto e não será carregado na inicialização de seu aplicativo, até que você o carregue.

<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>

O programa a seguir é a implementação do evento click, no qual a grade é carregada na página principal do aplicativo.

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

Quando o código acima for cumprido e executado, você verá apenas um botão. oTextblocks não são carregados na inicialização.

Agora, quando você clica no Show Elements botão, ele irá carregar os blocos de texto, o que irá melhorar o desempenho de inicialização do seu aplicativo.