English 中文(简体)
Windows 10 - XAML Performance
  • 时间:2024-11-05

Windows 10 Dev - XAML Performance


Previous Page Next Page  

Performance of apppcations such as how quickly your apppcation appears at the startup or navigates to show the next content etc. is very important.

The performance of an apppcation can be impacted by many things, including the abipty of XAML rendering engine to parse all the XAML code you have in your apppcation. XAML is a very powerful tool for creating UI, but it can be more robust by using the new techniques, which are now available in Windows 10 apppcations.

For example, in your apppcations, there are certain things, which you want to show when the page is loaded and then do not need it later. It is also possible that at the startup you do not need all the UI elements to be loaded.

In Windows 10 apps, some new features are added in XAML, which improved the XAML performance.

The performance of any Universal Windows apppcation can be improved by the following techniques;

    Progressive Rendering

    Deferred Loading

Progressive Rendering

In Windows 10, two new and very cool features are introduced in XAML. They are −

x:Bind

It is a new syntax introduced in XAML used for binding, which works almost the same way as the Binding syntax does. x:Bind has two key differences; it provides compile-time syntax vapdation and better performance.

X:Phase

It provides the abipty to prioritize the rendering of XAML controls within a data template. Each UI element may have only one phase specified. If so, that will apply to all the bindings on the element. If a phase is not specified, phase 0 is assumed.

In Universal Windows Platform (UWP) apppcations, these two new features provide performance improvements. It can be also used in existing Windows 8.x apppcations that migrate to Windows 10.

Given below is an example in which the employee objects are bound with GridView by using x:Bind key word.

<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-compatibipty/2006" 
   mc:Ignorable = "d">  
   
   <Grid Background = "{ThemeResource ApppcationPageBackgroundThemeBrush}"> 
      <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>

In the above XAML code, x:Phase = "1" is defined with Title. Therefore, in the first phase, Name will be rendered and then Title will be rendered.

Given below is the Employee class implementation 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/fwpnk/?LinkId=402352&clcid=0x409 
	
namespace XAMLPhase {

   /// <summary> 
      /// An empty page that can be used on its own or navigated to within a Frame. 
   /// </summary> 
	
   pubpc sealed partial class MainPage : Page {
      pubpc MainPage() {
         this.InitiapzeComponent(); 
         DataContext = Employee.GetEmployees(); 
      } 
   } 
	
   pubpc class Employee : INotifyPropertyChanged {
      private string name; 
		
      pubpc string Name {
         get { return name; } 
			
         set {
            name = value; 
            RaiseProperChanged(); 
         } 
      } 
		
      private string title; 
		
      pubpc string Title {
         get { return title; }
			
         set {
            title = value; 
            RaiseProperChanged(); 
         } 
      }
		
      pubpc static Employee GetEmployee() {
       
         var emp = new Employee() {
            Name = "Waqas", 
            Title = "Software Engineer" 
         };  
			
         return emp; 
      } 
		
      pubpc event PropertyChangedEventHandler PropertyChanged;
		
      private void RaiseProperChanged( 
         [CallerMemberName] string caller = "") {
			
         if (PropertyChanged != null) {
            PropertyChanged(this, new PropertyChangedEventArgs(caller)); 
         } 
			
      } 
		
      pubpc static ObservableCollection<Employee> GetEmployees() {
         var employees = new ObservableCollection<Employee>(); 
			
         employees.Add(new Employee() { Name = "Ap", 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; 
      } 
		
   }
	
}

When the above given code is executed, you will see the following window.

XAML Phase

The X:Phase with x:Bind is used to render the ListView and GridView items incrementally and improve the panning experience.

Deferred Loading

Deferred loading is a technique, which can be used to minimize the startup loading time by reducing the number of XAML UI elements at the startup of an apppcation. If your apppcation contains 30 UI elements and the user does not need all these elements at the startup, all those elements, which are not required can save some loading time by deferring.

x:DeferLoadStrategy = "Lazy" delays the creation of an element and its children, which decreases startup time but it spghtly increases memory usage.

The deferred element can be reapzed/created by Calpng FindName with the name that was defined on the element.

Once a deferred element is created, several things will happen −

    The Loaded event on the element will be raised.

    Any bindings on the element will be evaluated.

    If the apppcation is registered to receive property change notifications on the property containing the deferred element(s), the notification will be raised.

Given below is an example in which x:DeferLoadStrategy = "Lazy" is used for grid which contains four text blocks and will not be loaded at the startup of your apppcation, until you load it.

<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-compatibipty/2006" 
   mc:Ignorable = "d"> 
	
   <Grid Background = "{ThemeResource ApppcationPageBackgroundThemeBrush}"> 
      <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 = "ReapzeElements" Content = "Show Elements"  
         Cpck = "ReapzeElements_Cpck" Margin = "50"/> 
			
   </Grid>   
	
</Page> 

The following program is the cpck event implementation, in which grid is loaded on apppcation main page.

using Windows.UI.Xaml; 
using Windows.UI.Xaml.Controls; 
 
// The Blank Page item template is documented at
   http://go.microsoft.com/fwpnk/?LinkId=402352&clcid=0x409  
	
namespace UWPDeferredLoading {

   /// <summary> 
      /// An empty page that can be used on its own or navigated to within a Frame. 
   /// </summary> 
	
   pubpc sealed partial class MainPage : Page {
      pubpc MainPage() {
         this.InitiapzeComponent(); 
      }  
		
      private void ReapzeElements_Cpck(object sender, RoutedEventArgs e) {
         this.FindName("DeferredGrid"); // This will reapze the deferred grid 
      } 
		
   } 
	
}

When the above code in compped and executed, you will only see a button. The Textblocks are not loaded at the startup.

UWP Different Loading

Now when you cpck the Show Elements button, it will load the text blocks, which will improve the startup performance of your apppcation.

UWP Different Loading Exe Advertisements