Windows 10 Dev - Prestazioni XAML

Le prestazioni delle applicazioni, come la velocità con cui la tua applicazione appare all'avvio o naviga per mostrare il contenuto successivo, ecc. È molto importante.

Le prestazioni di un'applicazione possono essere influenzate da molti fattori, inclusa la capacità del motore di rendering XAML di analizzare tutto il codice XAML presente nell'applicazione. XAML è uno strumento molto potente per la creazione dell'interfaccia utente, ma può essere più robusto utilizzando le nuove tecniche, ora disponibili nelle applicazioni Windows 10.

Ad esempio, nelle tue applicazioni, ci sono alcune cose che vuoi mostrare quando la pagina viene caricata e quindi non ne hai bisogno in seguito. È anche possibile che all'avvio non sia necessario caricare tutti gli elementi dell'interfaccia utente.

Nelle app di Windows 10 vengono aggiunte alcune nuove funzionalità in XAML, che ha migliorato le prestazioni di XAML.

Le prestazioni di qualsiasi applicazione Windows universale possono essere migliorate con le seguenti tecniche;

  • Rendering progressivo
  • Caricamento differito

Rendering progressivo

In Windows 10, in XAML sono state introdotte due nuove e molto interessanti funzionalità. Sono -

x: Bind

Si tratta di una nuova sintassi introdotta in XAML utilizzata per l'associazione, che funziona quasi allo stesso modo di Binding la sintassi sì. x:Bindha due differenze fondamentali; fornisce la convalida della sintassi in fase di compilazione e prestazioni migliori.

X: fase

Offre la possibilità di dare la priorità al rendering dei controlli XAML all'interno di un modello di dati. Ogni elemento dell'interfaccia utente può avere solo una fase specificata. In tal caso, ciò si applicherà a tutti i collegamenti sull'elemento. Se una fase non è specificata, viene considerata la fase 0.

Nelle applicazioni UWP (Universal Windows Platform), queste due nuove funzionalità forniscono miglioramenti delle prestazioni. Può essere utilizzato anche nelle applicazioni Windows 8.x esistenti che migrano a Windows 10.

Di seguito è riportato un esempio in cui gli oggetti dipendente sono associati GridView usando x:Bind parola chiave.

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

Nel codice XAML sopra, x:Phase = "1"è definito con il titolo. Pertanto, nella prima fase,Name sarà renderizzato e poi Title sarà reso.

Di seguito è riportato il file Employee class implementazione in 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 il codice sopra indicato viene eseguito, vedrai la seguente finestra.

Il X:Phase con x:Bind viene utilizzato per eseguire il rendering del file ListView e GridView elementi in modo incrementale e migliorare l'esperienza di panoramica.

Caricamento differito

Il caricamento differito è una tecnica che può essere utilizzata per ridurre al minimo il tempo di caricamento all'avvio riducendo il numero di elementi dell'interfaccia utente XAML all'avvio di un'applicazione. Se la tua applicazione contiene 30 elementi dell'interfaccia utente e l'utente non ha bisogno di tutti questi elementi all'avvio, tutti quegli elementi che non sono richiesti possono far risparmiare tempo di caricamento differendo.

x:DeferLoadStrategy = "Lazy" ritarda la creazione di un elemento e dei suoi figli, il che riduce il tempo di avvio ma aumenta leggermente l'utilizzo della memoria.

L'elemento differito può essere realizzato / creato da Calling FindName con il nome definito sull'elemento.

Una volta creato un elemento differito, accadranno diverse cose:

  • Verrà generato l'evento Loaded sull'elemento.

  • Verranno valutati eventuali vincoli sull'elemento.

  • Se l'applicazione è registrata per ricevere notifiche di modifica della proprietà sulla proprietà contenente l'elemento o gli elementi rinviati, la notifica verrà generata.

Di seguito è riportato un esempio in cui x:DeferLoadStrategy = "Lazy" viene utilizzato per la griglia che contiene quattro blocchi di testo e non verrà caricata all'avvio dell'applicazione, fino a quando non la caricherai.

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

Il seguente programma è l'implementazione dell'evento click, in cui la griglia viene caricata nella pagina principale dell'applicazione.

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 il codice sopra è stato rispettato ed eseguito, vedrai solo un pulsante. IlTextblocks non vengono caricati all'avvio.

Ora quando fai clic su Show Elements pulsante, caricherà i blocchi di testo, il che migliorerà le prestazioni di avvio dell'applicazione.