Aracılığıyla paylaş


WinUI ve Windows Uygulama SDK'sı için XAML yüklemesini iyileştirme

Bellekteki nesneleri oluşturmak için XAML işaretlemesini ayrıştırmak karmaşık bir kullanıcı arabirimi için zaman alır. Burada, XAML işaretlemenizin ayrıştırma ve yükleme süresini ve WinUI uygulamanızın bellek verimliliğini geliştirmek için yapabileceğiniz bazı işlemler vardır.

Uygulama başlangıcında, yüklenen XAML işaretlemesini yalnızca ilk kullanıcı arabiriminiz için ihtiyacınız olan değerle sınırlayın. Sayfa kaynakları da dahil olmak üzere ilk sayfanızdaki işaretlemeyi inceleyin ve hemen gerekli olmayan ek öğeleri yüklemediğinizden emin olun. Bu öğeler kaynak sözlükleri, başlangıçta daraltılmış öğeler ve diğer öğelerin üzerine çizilmiş öğeler gibi çeşitli kaynaklardan gelebilir.

XAML'nizi verimlilik için en iyi duruma getirmek için dengeler elde etmeniz gerekir; her durum için her zaman tek bir çözüm yoktur. Burada bazı yaygın sorunlara göz atacak ve WinUI uygulamanız için doğru dengeleri sağlamak için kullanabileceğiniz yönergeler sağlıyoruz.

Öğe sayısını azaltma

XAML platformu çok sayıda öğe görüntüleme yeteneğine sahip olsa da, istediğiniz görselleri elde etmek için gereken en az sayıda öğeyi kullanarak uygulamanızın daha hızlı bir şekilde düzenlenmesini ve işlenmesini sağlayabilirsiniz.

Kullanıcı arabirimi denetimlerinizi nasıl düzenleyeceğiniz konusunda yaptığınız seçimler, uygulamanız başlatıldığında oluşturulan kullanıcı arabirimi öğelerinin sayısını etkiler. Düzeni iyileştirme hakkında daha ayrıntılı bilgi için bkz. XAML düzeninizi iyileştirme.

Her öğe her veri öğesi için yeniden oluşturulduğundan, veri şablonlarında öğe sayısı son derece önemlidir. Liste veya kılavuzdaki öğe sayısını azaltma hakkında bilgi için, WinUI için ListView ve GridView performansını iyileştirme makalesindeki Öğe başına öğe azaltma bölümüne bakın.

Burada, başlangıçta uygulamanızın yüklemesi gereken öğe sayısını azaltmanın diğer bazı yollarını inceleyeceğiz.

Öğe oluşturmayı erteleme

XAML işaretlemeniz hemen göstermediğiniz öğeler içeriyorsa, bu öğelerin yüklenmesini gösterilene kadar erteleyebilirsiniz. Örneğin, sekme benzeri bir kullanıcı arabiriminde ikincil sekme gibi görünür olmayan içeriğin oluşturulmasını geciktirebilirsiniz. Alternatif olarak, öğeleri varsayılan olarak kılavuz görünümünde gösterebilir, ancak kullanıcının verileri listede görüntülemesi için bir seçenek sağlayabilirsiniz. Gerekli olana kadar listeyi yüklemeyi geciktirebilirsiniz.

Öğenin ne zaman gösterileceğini denetlemek için Visibility özelliği yerine x:Load özniteliğini kullanın. Bir öğenin görünürlüğü Daraltıldı olarak ayarlandığında, işleme geçişi sırasında atlanır, ancak yine de nesne örneği maliyetlerini bellekte ödersiniz. Bunun yerine x:Load kullandığınızda, çerçeve gerekli olana kadar nesne örneğini oluşturmaz, bu nedenle bellek maliyetleri daha da düşüktür. Bunun dezavantajı, kullanıcı arabirimi yüklenmediğinde küçük bir bellek yükü (yaklaşık 600 bayt) ödemenizdir.

Uyarı

Windows Uygulama SDK'sında x:Load , hemen gerekmeyen XAML içeriği için önerilen ertelenmiş yükleme düzenidir.

Aşağıdaki örneklerde, kullanıcı arabirimi öğelerini gizlemek için farklı teknikler kullanıldığında öğe sayısı ve bellek kullanımı arasındaki fark gösterilmektedir. Aynı öğeleri içeren ListView ve GridView, sayfanın kök Kılavuzuna yerleştirilir. ListView görünmez, ancak GridView gösterilir. Bu örneklerin her birindeki XAML, ekranda aynı kullanıcı arabirimini oluşturur. Uygulamanızda öğe sayısını ve bellek kullanımını denetlemek için profil oluşturma ve performans araçlarını kullanın.

Seçenek 1 - Verimsiz

Burada ListView yüklenir, ancak Width'sı 0 olduğu için görünür değildir. ListView ve alt öğelerinin her biri görsel ağaçta oluşturulur ve belleğe yüklenir.

<!-- NOTE: EXAMPLE OF INEFFICIENT CODE; DO NOT COPY-PASTE. -->
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

    <ListView x:Name="List1" Width="0">
        <ListViewItem>Item 1</ListViewItem>
        <ListViewItem>Item 2</ListViewItem>
        <ListViewItem>Item 3</ListViewItem>
        <ListViewItem>Item 4</ListViewItem>
        <ListViewItem>Item 5</ListViewItem>
        <ListViewItem>Item 6</ListViewItem>
        <ListViewItem>Item 7</ListViewItem>
        <ListViewItem>Item 8</ListViewItem>
        <ListViewItem>Item 9</ListViewItem>
        <ListViewItem>Item 10</ListViewItem>
    </ListView>

    <GridView x:Name="Grid1">
        <GridViewItem>Item 1</GridViewItem>
        <GridViewItem>Item 2</GridViewItem>
        <GridViewItem>Item 3</GridViewItem>
        <GridViewItem>Item 4</GridViewItem>
        <GridViewItem>Item 5</GridViewItem>
        <GridViewItem>Item 6</GridViewItem>
        <GridViewItem>Item 7</GridViewItem>
        <GridViewItem>Item 8</GridViewItem>
        <GridViewItem>Item 9</GridViewItem>
        <GridViewItem>Item 10</GridViewItem>
    </GridView>
</Grid>

ListView'un yüklü olduğu canlı görsel ağaç. Sayfa için toplam öğe sayısı 89'dir.

Liste görünümüne sahip görsel ağacının ekran görüntüsü.

ListView ve alt öğeleri belleğe yüklenir.

ListView ve alt öğelerinin belleğe yüklendiğini gösteren Yönetilen Bellek Testi Uygulaması 1 noktalı E X E tablosunun ekran görüntüsü.

Seçenek 2 - Daha iyi

Burada, ListView Visibility olarak ayarlandı Collapsed (diğer XAML, özgün XAML ile aynıdır). ListView, görsel ağaçta oluşturulur, ancak onun alt öğeleri oluşturulmaz. Ancak, bunlar hala belleğe yüklenir, bu nedenle bellek kullanımı önceki örnekle aynıdır.

<ListView x:Name="List1" Visibility="Collapsed">

Katlanmış ListView ile canlı görsel ağacı. Sayfa için toplam öğe sayısı 46'dır.

Daraltılmış liste görünümüne sahip görsel ağacının ekran görüntüsü.

ListView ve alt öğeleri belleğe yüklenir.

ListView ve alt öğelerinin belleğe yüklendiğini gösteren Yönetilen Bellek Testi Uygulaması 1 nokta E X E tablosunun güncelleştirilmiş ekran görüntüsü.

Seçenek 3 - En verimli

Burada ListView'da x:Load özniteliği False olarak ayarlanmıştır (diğer XAML, özgün ile aynıdır). ListView, görsel ağaçta oluşturulmaz veya başlangıçta belleğe yüklenmez.

<ListView x:Name="List1" Visibility="Collapsed" x:Load="False">

ListView yüklü olmayan canlı görsel ağaç. Sayfa için toplam öğe sayısı 45'tir.

Liste görünümü yüklü olmayan görsel ağaç

ListView ve alt öğeleri belleğe yüklenmez.

Liste görünümüne sahip görsel ağaç

Uyarı

Bu örneklerdeki öğe sayıları ve bellek kullanımı çok küçüktür ve yalnızca kavramı göstermek için gösterilir. Bu örneklerde, x:Load kullanmanın yükü bellek tasarruflarından daha fazladır, bu nedenle uygulama yararlı olmaz. Ertelenmiş yüklemenin yardımcı olup olmayacağını belirlemek için uygulamanızda profil oluşturma araçlarını kullanmanız gerekir.

Düzen paneli özelliklerini kullanma

Düzen panellerinin Background özelliği vardır, bu nedenle yalnızca renklendirmek için panelin önüne Dikdörtgen koymanız gerekmez.

Verimsiz

<!-- NOTE: EXAMPLE OF INEFFICIENT CODE; DO NOT COPY-PASTE. -->
<Grid>
    <Rectangle Fill="Black"/>
</Grid>

Verimli

<Grid Background="Black"/>

Düzen panellerinin yerleşik kenarlık özellikleri de vardır, bu nedenle düzen panelinin çevresine Border öğesi yerleştirmeniz gerekmez. Daha fazla bilgi ve örnek için bkz . XAML düzeninizi iyileştirme .

Vektör tabanlı öğelerin yerine görüntüleri kullanma

Aynı vektör tabanlı öğeyi yeterince kez yeniden kullanırsanız, bunun yerine bir Image öğesini kullanmak daha verimli hale gelir. CPU her öğeyi ayrı ayrı oluşturması gerektiğinden vektör tabanlı öğeler daha pahalı olabilir. Görüntü dosyasının kodunun yalnızca bir kez çözülmesi gerekir.

Kaynakları ve kaynak sözlüklerini iyileştirme

Kaynak sözlüklerini genellikle uygulamanızın birden çok yerinde başvurmak istediğiniz kaynakları genel düzeyde depolamak için kullanırsınız. Örneğin, stiller, fırçalar, şablonlar vb.

Genel olarak ResourceDictionary, istenene kadar kaynakların örneğini oluşturmamak için iyileştirilmiştir. Ancak kaynakların gereksiz yere örneklenmemesi için kaçınmanız gereken durumlar vardır.

x:Name ile kaynaklar

Kaynaklarınıza başvurmak için x:Key özniteliğini kullanın. x:Name özniteliğine sahip herhangi bir kaynak platform optimizasyonundan faydalanmaz; bunun yerine, ResourceDictionary oluşturulurken hemen örneklenir. Bunun nedeni x:Name'in platforma uygulamanızın bu kaynağa alan erişimine ihtiyacı olduğunu, dolayısıyla platformun bu kaynağa başvuruyu barındıracak bir şey oluşturması gerektiğini söylemesidir.

UserControl'de ResourceDictionary

UserControl içinde tanımlanan ResourceDictionary bir ceza taşır. Platform, UserControl'ün her örneği için böyle bir ResourceDictionary'nin bir kopyasını oluşturur. Çok kullanılan bir UserControl'leriniz varsa ResourceDictionary'yi UserControl'ün dışına taşıyın ve sayfa düzeyine yerleştirin.

Kaynak ve Kaynak Sözlüğü kapsamı

Bir sayfa farklı bir dosyada tanımlanan bir kullanıcı denetimine veya kaynağa başvuruda bulunursa, çerçeve bu dosyayı da ayrıştırıyor demektir.

Burada InitialPage.xaml, ExampleResourceDictionary.xaml dosyasından bir kaynak kullandığından, başlangıçta ExampleResourceDictionary.xaml dosyasının tamamı ayrıştırılmalıdır.

InitialPage.xaml

<Page x:Class="ExampleNamespace.InitialPage" ...>
    <Page.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="ExampleResourceDictionary.xaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Page.Resources>

    <Grid>
        <TextBox Foreground="{StaticResource TextBrush}"/>
    </Grid>
</Page>

ExampleResourceDictionary.xaml

<ResourceDictionary>
    <SolidColorBrush x:Key="TextBrush" Color="#FF3F42CC"/>

    <!--This ResourceDictionary contains many other resources that
        are used in the app, but are not needed during startup.-->
</ResourceDictionary>

Uygulamanızın tamamında birçok sayfada bir kaynak kullanıyorsanız, bunu App.xaml'de depolamak iyi bir uygulamadır ve yinelemeyi önler. Ancak App.xaml uygulama başlangıcında ayrıştırılır, bu nedenle bu sayfa ilk sayfa olmadığı sürece yalnızca bir sayfada kullanılan tüm kaynaklar sayfanın yerel kaynaklarına yerleştirilmelidir. Bu örnekte, başlangıç sayfası olmayan yalnızca bir sayfa tarafından kullanılan kaynakları içeren App.xaml gösterilmektedir. Bu, başlatma süresini önemli ölçüde artırır.

App.xaml

<!-- NOTE: EXAMPLE OF INEFFICIENT CODE; DO NOT COPY-PASTE. -->
<Application ...>
     <Application.Resources>
        <SolidColorBrush x:Key="DefaultAppTextBrush" Color="#FF3F42CC"/>
        <SolidColorBrush x:Key="InitialPageTextBrush" Color="#FF3F42CC"/>
        <SolidColorBrush x:Key="SecondPageTextBrush" Color="#FF3F42CC"/>
        <SolidColorBrush x:Key="ThirdPageTextBrush" Color="#FF3F42CC"/>
    </Application.Resources>
</Application>

InitialPage.xaml

<!-- NOTE: EXAMPLE OF INEFFICIENT CODE; DO NOT COPY-PASTE. -->
<Page x:Class="ExampleNamespace.InitialPage" ...>
    <StackPanel>
        <TextBox Foreground="{StaticResource InitialPageTextBrush}"/>
    </StackPanel>
</Page>

SecondPage.xaml

<!-- NOTE: EXAMPLE OF INEFFICIENT CODE; DO NOT COPY-PASTE. -->
<Page x:Class="ExampleNamespace.SecondPage" ...>
    <StackPanel>
        <Button Content="Submit" Foreground="{StaticResource SecondPageTextBrush}"/>
    </StackPanel>
</Page>

Bu örneği daha verimli hale getirmek için SecondPageTextBrushSecondPage.xaml ve ThirdPageTextBrushThirdPage.xaml dosyalarına taşıyın. InitialPageTextBrush uygulama kaynaklarının her durumda uygulama başlangıcında ayrıştırılması gerektiğinden App.xaml içinde kalabilir.

Aynı görünen birden çok fırçayı tek bir kaynakta birleştirme

XAML platformu yaygın olarak kullanılan nesneleri önbelleğe almaya çalışır, böylece mümkün olduğunca sık yeniden kullanılabilirler. Ancak XAML, bir işaretleme parçasında bildirilen bir fırçanın başka bir işaretlemede bildirilen fırçayla aynı olup olmadığını kolayca anlayamaz. Buradaki örnek, göstermek için SolidColorBrush kullanır ancak durum Gradyan Fırça ile daha büyük bir olasılıkla ve daha önemlidir. Ayrıca önceden tanımlanmış renkleri kullanan fırçaları denetleyin; örneğin, "Orange" ve "#FFFFA500" aynı renktedir.

Verimsiz

<!-- NOTE: EXAMPLE OF INEFFICIENT CODE; DO NOT COPY-PASTE. -->
<Page ... >
    <StackPanel>
        <TextBlock>
            <TextBlock.Foreground>
                <SolidColorBrush Color="#FFFFA500"/>
            </TextBlock.Foreground>
        </TextBlock>
        <Button Content="Submit">
            <Button.Foreground>
                <SolidColorBrush Color="#FFFFA500"/>
            </Button.Foreground>
        </Button>
    </StackPanel>
</Page>

Yinelemeyi düzeltmek için fırçayı kaynak olarak tanımlayın. Diğer sayfalardaki denetimler aynı fırçayı kullanıyorsa, bunu App.xaml'e taşıyın.

Verimli

<Page ... >
    <Page.Resources>
        <SolidColorBrush x:Key="BrandBrush" Color="#FFFFA500"/>
    </Page.Resources>

    <StackPanel>
        <TextBlock Foreground="{StaticResource BrandBrush}" />
        <Button Content="Submit" Foreground="{StaticResource BrandBrush}" />
    </StackPanel>
</Page>

Fazla çizimi en aza indirme

Aynı ekran piksellerinde birden fazla nesne çizildiğinde üzerine çizim yapılır. Bu kılavuz ile öğe sayısını en aza indirme isteği arasında bazen bir denge olduğunu unutmayın.

Görsel tanılama olarak DebugSettings.IsOverdrawHeatMapEnabled kullanın. Sahnede olduğunu bilmediğiniz nesneler çizildiğini fark edebilirsiniz.

Saydam veya gizli öğeler

Bir öğe saydam olduğu veya diğer öğelerin arkasında gizlendiği için görünmüyorsa ve düzene katkıda bulunmuyorsa, öğeyi silin. Öğe ilk görsel durumunda görünmüyorsa ancak diğer görsel durumlarında görünüyorsa, durumunu denetlemek için x:Load kullanın veya Görünürlük öğesinin kendisinde Daraltıldı olarak ayarlayın ve değeri uygun durumlarda Görünür olarak değiştirin. Sezgisel yöntemin istisnaları olacaktır: Genel olarak, görsel durumların çoğunda bir özelliğin değeri, öğe üzerinde yerel olarak ayarlanmasıyla en iyi şekilde belirlenir.

Bileşik öğeler

Etki oluşturmak için birden çok öğeyi katmanlama yerine bileşik öğe kullanın. Bu örnekte sonuç, iki tonlu bir şekildir; üst yarısı Grid'in arka planından dolayı siyah, alt yarısı ise yarı saydam beyaz Dikdörtgen'in, siyah Grid arka planı üzerinde alfa karışımı ile oluşturduğu gri renktedir. Burada, sonucu elde etmek için gereken piksellerin 150% dolduruluyor.

Verimsiz

<!-- NOTE: EXAMPLE OF INEFFICIENT CODE; DO NOT COPY-PASTE. -->
<Grid Background="Black">
    <Grid.RowDefinitions>
        <RowDefinition Height="*"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <Rectangle Grid.Row="1" Fill="White" Opacity=".5"/>
</Grid>

Verimli

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="*"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <Rectangle Fill="Black"/>
    <Rectangle Grid.Row="1" Fill="#FF7F7F7F"/>
</Grid>

Düzen panelleri

Düzen panelinin iki amacı olabilir: bir alanı renklendirmek ve alt öğeleri yerleştirme. Z sıralamasında daha geride olan bir öğe zaten bir alanı renklendiriyorsa, öndeki yerleşim panelinin bu alanı boyaması gerekmez; bunun yerine, alt öğelerini yerleştirmeye odaklanabilir. İşte bir örnek.

Verimsiz

<!-- NOTE: EXAMPLE OF INEFFICIENT CODE; DO NOT COPY-PASTE. -->
<GridView Background="Blue">
    <GridView.ItemTemplate>
        <DataTemplate>
            <Grid Background="Blue"/>
        </DataTemplate>
    </GridView.ItemTemplate>
</GridView>

Verimli

<GridView Background="Blue">
    <GridView.ItemTemplate>
        <DataTemplate>
            <Grid/>
        </DataTemplate>
    </GridView.ItemTemplate>
</GridView>

Kılavuzda isabet sınaması yapılması gerekiyorsa, üzerinde bir arka plan değeri Transparent ayarlayın.

Sınır -ları

Bir nesnenin çevresine kenarlık çizmek için Border öğesi kullanın. Bu örnekte, Kılavuz, TextBox çevresinde geçici olarak sınır oluşturmak için kullanılır. Ancak ortadaki hücredeki tüm pikseller üst üste çizilir.

Verimsiz

<!-- NOTE: EXAMPLE OF INEFFICIENT CODE; DO NOT COPY-PASTE. -->
<Grid Background="Blue" Width="300" Height="45">
    <Grid.RowDefinitions>
        <RowDefinition Height="5"/>
        <RowDefinition/>
        <RowDefinition Height="5"/>
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="5"/>
        <ColumnDefinition/>
        <ColumnDefinition Width="5"/>
    </Grid.ColumnDefinitions>
    <TextBox Grid.Row="1" Grid.Column="1"></TextBox>
</Grid>

Verimli

<Border BorderBrush="Blue" BorderThickness="5" Width="300" Height="45">
    <TextBox/>
</Border>

Kenar boşlukları

Kenar boşluklarını dikkate alın. Negatif kenar boşlukları başka bir öğenin işleme sınırlarına genişletilip fazla çizime neden olursa, iki komşu öğe büyük olasılıkla yanlışlıkla çakışacaktır.

Statik içeriği önbelleğe alma

Başka bir fazla çizim kaynağı da birçok çakışan öğeden yapılmış bir şekildir. Bileşik şekli içeren UIElement üzerinde CacheMode'uBitmapCache olarak ayarlarsanız, platform öğeyi bir kez bit eşlem olarak işler ve bu bit eşlemi her karede yeniden çizmek yerine kullanır.

Verimsiz

<Canvas Background="White">
    <Ellipse Height="40" Width="40" Fill="Blue"/>
    <Ellipse Canvas.Left="21" Height="40" Width="40" Fill="Blue"/>
    <Ellipse Canvas.Top="13" Canvas.Left="10" Height="40" Width="40" Fill="Blue"/>
</Canvas>

Üç düz daire içeren Venn diyagramı

Yukarıdaki görüntü sonuçtur, ancak aşırı çizilmiş bölgelerin haritası burada sunulmaktadır. Daha koyu kırmızı, daha yüksek miktarda fazla render olduğunu işaret eder.

Çakışan alanları gösteren Venn diyagramı

Verimli

<Canvas Background="White" CacheMode="BitmapCache">
    <Ellipse Height="40" Width="40" Fill="Blue"/>
    <Ellipse Canvas.Left="21" Height="40" Width="40" Fill="Blue"/>
    <Ellipse Canvas.Top="13" Canvas.Left="10" Height="40" Width="40" Fill="Blue"/>
</Canvas>

CacheMode kullanımına dikkat edin. Alt şekillerden herhangi biri animasyon içeriyorsa, bit eşlem önbelleğinin her karede muhtemelen yeniden oluşturulması gerekeceğinden ve bu da tekniğin amacını geçersiz kılacağından, bu tekniği kullanmayın.

Derlenmiş XAML çıktısı kullanma

Windows Uygulama SDK'sı, derlemenin bir parçası olarak XAML'yi ikili bir gösterime derler ve bu da çalışma zamanında metin ayrıştırma maliyetlerini önler. Derlenen biçim ayrıca görsel durumlar, kaynak sözlükleri ve stiller gibi yaygın XAML türleri için yük ve ağaç oluşturmayı iyileştirir.

Yerleşik WinUI denetimleri ve sözlükleri bu işlem hattından zaten yararlanır. Kendi WinUI uygulamanız için, oluşturulan işaretleme derleme çıkışının çalışma zamanında kullanılabilir olması için normal XAML derleme adımlarını etkin tutun.