Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
Az XAML-jelölés elemzése az objektumok memóriában való létrehozásához időigényes egy összetettebb felhasználói felület esetében. Az alábbiakban néhány dolgot tehet az XAML-korrektúra elemzési és betöltési idejének, valamint a WinUI-alkalmazás memóriahatékonyságának javításához.
Az alkalmazás indításakor korlátozza a betöltött XAML jelölést, amelyre csak a kezdeti felhasználói felülethez van szükség. Vizsgálja meg a kezdeti oldalon található korrektúrát, beleértve a laperőforrásokat is, és győződjön meg arról, hogy nem tölt be azonnal felesleges elemeket. Ezek az elemek számos forrásból származhatnak, például erőforrás-szótárakból, kezdetben elrejtett állapotban lévő elemekből és más elemek fölé rajzolt elemekből.
Az XAML hatékonyságának optimalizálása kompromisszumot igényel; nincs mindig egyetlen megoldás minden helyzetben. Itt áttekintünk néhány gyakori problémát, és útmutatást adunk a WinUI-alkalmazás megfelelő kompromisszumoinek eléréséhez.
Elemek számának minimalizálása
Bár az XAML platform nagy számú elem megjelenítésére képes, az alkalmazás a kívánt vizualizációk eléréséhez szükséges legkevesebb elem használatával gyorsabban elrendezhető és renderelhető.
A felhasználói felület vezérlőinek elrendezésében meghozott döntések befolyásolják az alkalmazás indításakor létrehozott felhasználói felületi elemek számát. Az elrendezés optimalizálásáról további információt az XAML-elrendezés optimalizálása című témakörben talál.
Az elemszám rendkívül fontos az adatsablonokban, mert minden elem újra létrejön az egyes adatelemekhez. A lista vagy rács elemszámának csökkentéséről további információt a WinUI-ra vonatkozó ListView és GridView teljesítmény optimalizálása című cikkben talál.
Itt bemutatunk néhány egyéb módszert, amelyekkel csökkentheti az alkalmazás indításkor betöltendő elemeinek számát.
Elem létrehozásának halasztás
Ha az XAML-jelölés olyan elemeket tartalmaz, amelyeket nem jelenít meg azonnal, elhalaszthatja az elemek betöltését, amíg azokat meg nem jeleníti. Késleltetheti például a nem látható tartalmak, például egy másodlagos lap létrehozását egy tabulátorszerű felhasználói felületen. Előfordulhat, hogy alapértelmezés szerint rács nézetben jeleníti meg az elemeket, de megadhat egy lehetőséget, hogy a felhasználó ehelyett egy listában tekinthesse meg az adatokat. Ha szükséges, késleltetheti a lista betöltését.
A Láthatóság tulajdonság helyett az x:Load attribútummal szabályozhatja, hogy mikor jelenjen meg egy elem. Amikor egy elem láthatósága Összecsukva értékre van állítva, az a renderelési folyamat során ki van hagyva, de az objektumpéldány költségeit továbbra is meg kell fizetni a memóriában. Ha inkább x:Load parancsot használ, a keretrendszer csak akkor hozza létre az objektumpéldányt, ha szükség van rá, így a memóriaköltségek még alacsonyabbak. A hátránya, hogy kis memóriaterhelést (körülbelül 600 bájtot) kell fizetnie, ha a felhasználói felület nincs betöltve.
Megjegyzés:
A Windows App SDK-ban az x:Load a javasolt késleltetett betöltési minta az XAML-tartalomhoz, amelyre nincs szükség azonnal.
Az alábbi példák az elemek számának és a memóriahasználatnak a különbségét mutatják, ha a felhasználói felület elemeinek elrejtésére különböző technikákat használnak. Az azonos elemeket tartalmazó ListView és GridView a lap gyökérrácsába kerül. A ListView nem látható, de megjelenik a GridView. Az ezekben a példákban szereplő XAML ugyanazt a felhasználói felületet hozza létre a képernyőn. A profilkészítéshez és a teljesítményhez használható eszközökkel ellenőrizheti az elemek számát és a memóriahasználatot az alkalmazásban.
1. lehetőség – Nem hatékony
Itt a ListView be van töltve, de nem látható, mert Width az 0. A ListView és annak minden gyermekeleme a vizualizációfán jön létre, és betöltődik a memóriába.
<!-- 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>
Élő vizualizációfa a ListView betöltéssel. Az oldal teljes elemszáma 89.
A ListView és az alárendelt elemek be vannak töltve a memóriába.
2. lehetőség – Jobb
Itt a ListView Visibility beállítása Collapsed értékre történt (a többi XAML megegyezik az eredetivel). A ListView a vizuális fában jön létre, gyermekelemeit azonban nem hozza létre. Ezek azonban továbbra is betöltve vannak a memóriába, így a memóriahasználat megegyezik az előző példával.
<ListView x:Name="List1" Visibility="Collapsed">
Élő vizuális fa, amely össze van csukva a ListView-val. Az oldal teljes elemszáma 46.
A ListView és gyermekei betöltve vannak a memóriába.
3. lehetőség – Leghatékonyabb
Itt a ListView x:Load attribútumát False értékre állították (a másik XAML az eredetivel megegyezik). A ListView nem jön létre a vizualizációfán, és nem töltődik be a memóriába indításkor.
<ListView x:Name="List1" Visibility="Collapsed" x:Load="False">
Élő vizualizációfa, amelyen nincs betöltve a ListView. Az oldal teljes elemszáma 45.
A ListView és komponensei nincsenek betöltve a memóriába.
Megjegyzés:
Az elemek száma és a memóriahasználat ezekben a példákban nagyon kicsi, és csak a koncepció bemutatására mutat. Ezekben a példákban az x:Load használata nagyobb, mint a memóriamegtakarítás, így az alkalmazás nem járna előnyökkel. Az alkalmazás profilkészítési eszközeivel állapítsa meg, hogy a késleltetett betöltés segít-e.
Elrendezéspanel tulajdonságainak használata
Az elrendezéspanelek háttértulajdonságúak , ezért nem kell téglalapot elhelyezni a panel elé csak színezéshez.
Hatékony
<!-- NOTE: EXAMPLE OF INEFFICIENT CODE; DO NOT COPY-PASTE. -->
<Grid>
<Rectangle Fill="Black"/>
</Grid>
Hatékony
<Grid Background="Black"/>
Az elrendezéspanelek beépített szegélytulajdonságokat is rendelkeznek, ezért nem kell szegélyelemet elhelyeznie az elrendezéspanelen. További információkért és példákért tekintse meg az XAML-elrendezés optimalizálása című témakört.
Képek használata vektoralapú elemek helyett
Ha elégszer újra felhasználja ugyanazt a vektoralapú elemet, hatékonyabb lesz a képelem használata. A vektoralapú elemek drágábbak lehetnek, mivel a CPU-nak külön kell létrehoznia az egyes elemeket. A képfájlt csak egyszer kell dekódolni.
Erőforrások és erőforrás-szótárak optimalizálása
Általában erőforrásszótárak használatával tárolhatja az alkalmazás több pontján hivatkozni kívánt erőforrásokat valamelyest globális szinten. Stílusok, ecsetek, sablonok stb.
A ResourceDictionary általában úgy van optimalizálva, hogy elkerülje az erőforrások példányosítását, amíg a rendszer nem kéri őket. Vannak azonban olyan helyzetek, amelyeket el kell kerülnie, hogy az erőforrások ne legyenek szükségtelenül példányosítva.
X:Névvel rendelkező erőforrások
Az x:Key attribútummal hivatkozhat az erőforrásokra. Az x:Name attribútummal rendelkező erőforrások nem fogják kihasználni a platformoptimalizálás előnyeit; ehelyett a ResourceDictionary létrehozása után azonnal példányosítva lesz. Ez azért történik, mert az x:Name azt jelzi a platformnak, hogy az alkalmazásnak mezőhozzáférésre van szüksége ehhez az erőforráshoz, ezért a platformnak létre kell hoznia valamit, hogy hivatkozhasson rá.
ResourceDictionary a UserControlban
A UserControlban definiált ResourceDictionary büntetést von maga után. A platform létrehozza az ilyen ResourceDictionary másolatát a UserControl minden példányához. Ha olyan UserControlt használ, amelyet sokat használ, helyezze ki a ResourceDictionaryt a UserControlból, és helyezze az oldalszintre.
Erőforrás- és ResourceDictionary-hatókör
Ha egy lap egy másik fájlban definiált felhasználói vezérlőre vagy erőforrásra hivatkozik, akkor a keretrendszer ezt a fájlt is elemzi.
Mivel az InitialPage.xaml az ExampleResourceDictionary.xaml egyik erőforrását használja, az ExampleResourceDictionary.xaml egészét az indításkor kell elemezni.
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>
Ha az alkalmazás számos oldalán használ erőforrást, akkor az App.xaml-ben való tárolása ajánlott, és elkerüli a duplikációt. Az App.xaml azonban az alkalmazás indításakor van elemezve, ezért minden olyan erőforrást, amelyet csak egy oldalon használnak, kivéve, ha ez a lap a kezdeti oldal, a lap helyi erőforrásaiba kell helyezni. Ebben a példában az App.xaml olyan erőforrásokat mutat be, amelyeket csak egy olyan oldal használ, amely nem a kezdeti oldal. Ez szükségtelenül növeli az indítási időt.
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>
A példa hatékonyabbá tétele érdekében lépjen SecondPageTextBrush a SecondPage.xaml fájlba, és lépjen ThirdPageTextBrush a ThirdPage.xaml fájlba.
InitialPageTextBrush az App.xaml-ben maradhat, mert az alkalmazás erőforrásait minden esetben elemezni kell az alkalmazás indításakor.
Több, azonosnak tűnő ecsetet vonj össze egy erőforrásként.
Az XAML platform megpróbálja gyorsítótárazni a gyakran használt objektumokat, hogy a lehető leggyakrabban újra felhasználhatók legyenek. Az XAML azonban nem tudja könnyen megállapítani, hogy az egyik jelölőelemben deklarált ecset megegyezik-e a másikban deklarált ecsettel. Az alábbi példa a SolidColorBrush használatával mutatja be, de a GradientBrush esetében az eset valószínűbb és fontosabb. Ellenőrizze az előre definiált színeket használó keféket is; például "Orange""#FFFFA500" ugyanaz a szín.
Hatékony
<!-- 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>
A duplikáció kijavításához definiálja az ecsetet erőforrásként. Ha más lapok vezérlői ugyanazt az ecsetet használják, helyezze át az App.xaml fájlba.
Hatékony
<Page ... >
<Page.Resources>
<SolidColorBrush x:Key="BrandBrush" Color="#FFFFA500"/>
</Page.Resources>
<StackPanel>
<TextBlock Foreground="{StaticResource BrandBrush}" />
<Button Content="Submit" Foreground="{StaticResource BrandBrush}" />
</StackPanel>
</Page>
Túlrajzolás minimalizálása
A túlméretezettség akkor fordul elő, ha egynél több objektumot rajzolnak ugyanabban a képernyő-képpontban. Vegye figyelembe, hogy néha van kompromisszum ezen útmutató és az elemek számának minimalizálásának igénye között.
Használja a DebugSettings.IsOverdrawHeatMapEnabled-t, mint vizuális diagnosztikai eszközt. Előfordulhat, hogy olyan tárgyakat rajzolnak meg, amelyekről nem tudta, hogy a jelenetben voltak.
Áttetsző vagy rejtett elemek
Ha egy elem nem látható, mert transzparens vagy rejtett más elemek mögött, és nem járul hozzá az elrendezéshez, törölje. Ha az elem nem látható a kezdeti vizualizációs állapotban, de más vizualizációs állapotokban is látható, akkor az x:Betöltés funkcióval szabályozhatja az állapotát, vagy beállíthatja , hogy a Láthatóság összecsukva legyen az elemen, és módosítsa az értéket Látható értékre a megfelelő állapotokban. Erre a heurisztikára vannak kivételek: általában az az érték, amelyet egy tulajdonság a vizuális állapotok többségében birtokol, a legjobb, ha lokálisan van beállítva az elemen.
Összetett elemek
Több elem rétegezése helyett használjon összetett elemet egy effektus létrehozásához. Ebben a példában az eredmény egy kétárnyalatú alakzat, amelyben a felső fél fekete a Rács hátteréből, az alsó fele pedig szürke a félig átlátszó fehér Téglalapból, amely a Rács fekete hátterébe van blendelve. Itt az eredmény eléréséhez szükséges képpontok közül 150% töltődik ki.
Hatékony
<!-- 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>
Hatékony
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Rectangle Fill="Black"/>
<Rectangle Grid.Row="1" Fill="#FF7F7F7F"/>
</Grid>
Elrendezés panelek
Az elrendezéspanelnek két célja lehet: egy terület színezése és a gyermekelemek elrendezése. Ha egy z-sorrendben távolabbi elem már színez egy területet, akkor az előtér elrendezési paneljének nem kell ezt a területet festenie; ehelyett a gyermekek elhelyezésére összpontosíthat. Íme egy példa.
Hatékony
<!-- NOTE: EXAMPLE OF INEFFICIENT CODE; DO NOT COPY-PASTE. -->
<GridView Background="Blue">
<GridView.ItemTemplate>
<DataTemplate>
<Grid Background="Blue"/>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
Hatékony
<GridView Background="Blue">
<GridView.ItemTemplate>
<DataTemplate>
<Grid/>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
Ha a rácsot tesztelhetőnek kell lennie, akkor állítson be egy háttérértéket Transparent rajta.
Határok
Szegélyelem használatával rajzoljon szegélyt egy objektum köré. Ebben a példában egy rácsot használunk ideiglenes szegélyként egy Szövegdoboz körül. De a középső cellában lévő összes képpont túl van állítva.
Hatékony
<!-- 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>
Hatékony
<Border BorderBrush="Blue" BorderThickness="5" Width="300" Height="45">
<TextBox/>
</Border>
Margók
Ügyeljen a margókra. Két szomszédos elem átfedésben lesz, esetleg véletlenül, ha a negatív margók egy másik elem renderelési határaira terjednek ki, és felülírást okoznak.
Statikus tartalom gyorsítótárazása
Az átlapolások egyik forrása egy sok egymást átfedő elemből készült alakzat. Ha a CacheMode-otBitmapCache értékre állítja az összetett alakzatot tartalmazó UIElementen , akkor a platform egyszer bitképké alakítja az elemet, és ezt a bitképet használja minden egyes keretben a túldralódás helyett.
Hatékony
<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>
A fenti kép az eredmény, de itt látható a felülírt régiók térképe. A sötétebb piros a nagyobb mértékű túldrágultságra utal.
Hatékony
<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>
Figyelje meg a CacheMode használatát. Ne használja ezt a technikát, ha az alalakzatok bármelyike animálódik, mert a bitkép-gyorsítótárat valószínűleg minden egyes képkockán újra kell generálni, ez pedig ellentmond a célnak.
Lefordított XAML-kimenet használata
A Windows App SDK az XAML-t bináris reprezentációvá fordítja a build részeként, így elkerüli a futásidőben felmerülő szövegelemzési költségeket. A lefordított formátum emellett optimalizálja a betöltést és a fa létrehozását a gyakori XAML-típusok esetében, mint például a vizuális állapotok, az erőforrás-szótárak és stílusok.
A beépített WinUI-vezérlők és szótárak már élvezik ezt a folyamatot. Saját WinUI-alkalmazása esetén hagyja engedélyezve a normál XAML fordítási lépéseket, hogy a létrehozott korrektúrafordítási kimenet futásidőben is elérhető legyen.
Kapcsolódó cikkek
Windows developer