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.
WinUI-alkalmazásokat hozhat létre a Windows App SDK-val, amelyek az indítási munka csökkentésével, az első keret egyszerűsítésével és a nem kritikus funkciók betöltésével gyorsan elindulnak, miután az ablak interaktív.
Ajánlott eljárások az alkalmazás indítási teljesítményéhez
A felhasználók részben azt érzékelik, hogy az alkalmazás gyors vagy lassú attól függően, hogy mennyi ideig tart az indítás. A jelen témakör alkalmazásában az alkalmazás indítási ideje akkor kezdődik, amikor a felhasználó elindítja az alkalmazást, és akkor ér véget, amikor a felhasználó értelmes módon kommunikálhat az alkalmazással. Ez a cikk javaslatokat tartalmaz arra vonatkozóan, hogyan lehet jobb indítási teljesítményt elérni egy WinUI-alkalmazásból.
Az alkalmazás indítási idejének mérése
Ügyeljen arra, hogy néhányszor indítsa el az alkalmazást, mielőtt ténylegesen megméri annak indítási idejét. Ez alapszintet biztosít a méréséhez, és segít biztosítani, hogy a lehető legésszerűbben rövid indítási időt mérje.
Olyan méréseket végez, amelyek a végfelhasználó által tapasztaltakra jellemzőek. A Measure Release reprezentatív hardverre épül, a hideg és a meleg indítást is vizsgálja, és a folyamat megjelenéséig eltelt idő helyett az első interaktív keretre összpontosít.
Halassza el a munkát, amíg csak lehetséges
Az alkalmazás indítási idejének javítása érdekében csak azt a munkát végezze el, amelyet feltétlenül el kell végezni, hogy a felhasználó elkezdhesse használni az alkalmazást. Ez különösen hasznos lehet, ha képes késleltetni a további egységek betöltését. A közös nyelvi futtatókörnyezet első használatkor betölt egy assemblyt. Ha minimalizálni tudja a betöltött könyvtárak számát, javíthatja az alkalmazás indítási idejét és memóriahasználatát.
Hosszú ideig futó munkát függetlenül végezni
Az alkalmazás akkor is interaktív lehet, ha az alkalmazásnak vannak olyan részei, amelyek nem teljesen működőképesek. Ha például az alkalmazás olyan adatokat jelenít meg, amelyek lekérése eltarthat egy ideig, az alkalmazás indítási kódjától függetlenül hajthatja végre a kódot az adatok aszinkron beolvasásával. Ha az adatok elérhetők, töltse ki az alkalmazás felhasználói felületét az adatokkal.
Az adatokat lekérő API-k többsége aszinkron, ezért valószínűleg aszinkron módon fogja lekérni az adatokat. További információ: Aszinkron programozás aszinkronnal és várakozással. Ha olyan munkát végez, amely nem aszinkron API-kat használ, az Task osztály használatával hosszú ideig futó munkát végezhet, hogy ne tiltsa le a felhasználót az alkalmazással való interakcióban. Így az alkalmazás rugalmasan reagál az adatok betöltése közben.
Ha az alkalmazás különösen hosszú időt vesz igénybe a felhasználói felület egy részének betöltéséhez, fontolja meg egy üzenet megjelenítését ezen a területen, például a "Legfrissebb adatok lekérése", hogy a felhasználók tudják, hogy az alkalmazás még feldolgozás alatt áll.
Indítási idő minimalizálása
A legegyszerűbb alkalmazások kivételével minden alkalmazás esetén érzékelhető mennyiségű időre van szükség az erőforrások betöltéséhez, az XAML elemzéséhez, az adatstruktúrák beállításához és a logika futtatásához az indítás során. WinUI-alkalmazások esetén négy fázisban érdemes átgondolni az indítást: folyamatindítás, ablaklétrehozás, főoldal-létrehozás és elrendezés/renderelés az első kerethez.
Az indítási időszak az a pillanat, amikor a felhasználó elindítja az alkalmazást, és attól a pillanattól kezdve, hogy az alkalmazás működőképessé válik. Ez kritikus időszak, mert ez a felhasználó első benyomása az alkalmazásról. A felhasználók azonnali és folyamatos visszajelzést várnak a rendszertől és az alkalmazásoktól. A rendszer és az alkalmazás hibásnak vagy rosszul megtervezettnek minősül, ha az alkalmazások nem indulnak el gyorsan.
Bevezetés az indítás fázisaiba
Az indítás számos mozgó részre oszlik, és mindegyiket össze kell hangolni a legjobb felhasználói élmény érdekében. Az alábbi lépések az alkalmazást megnyitó felhasználó és a megjelenített alkalmazástartalom között történnek.
- A folyamat elindul, és a sablon által generált indítási kód meghívja a
Main. - Az
Applicationobjektum létrejön.- Az alkalmazáskonstruktor meghívja a
InitializeComponent-t, amely miatt aApp.xamlelemzésre kerül, és objektumok jönnek létre.
- Az alkalmazáskonstruktor meghívja a
-
Az Application.OnLaunched aktiválódik.
- Az alkalmazáskód létrehozza a fő ablakot, kijelöli a kezdeti tartalmat, és meghívja
Activate. - A főoldal-konstruktor meghívja a
InitializeComponentkomponenst, amely az oldal XAML-jének elemzését okozza, és objektumokat hoz létre.
- Az alkalmazáskód létrehozza a fő ablakot, kijelöli a kezdeti tartalmat, és meghívja
- Az XAML-keretrendszer futtatja az elrendezési fázist, beleértve a mérést és az elrendezést is.
-
ApplyTemplateA vezérlősablon tartalma minden vezérlőhöz létrejön, ami általában az indítás során az elrendezési idő zömét teszi ki.
-
- A renderelés vizualizációkat hoz létre az ablak tartalmához.
- Megjelenik az első keret, és az indítás utáni munka aszinkron módon folytatódik.
Csökkentsd a teendőidet a startup útvonalán
Tartsa az indítási kód útvonalát mentesen az első kerethez szükségtelen elemek nélkül.
- Ha olyan felhasználói DLL-ekkel rendelkezik, amelyek az első keret során nem szükséges vezérlőket tartalmaznak, érdemes lehet késleltetni a betöltésüket.
- Ha a felhasználói felület egy része a felhőből származó adatoktól függ, ossza fel a felhasználói felületet. Először hozza létre azt a felhasználói felületet, amely nem függ a felhőbeli adatoktól, majd aszinkron módon hozza létre a felhőfüggő felhasználói felületet. Érdemes megfontolnia az adatok helyi gyorsítótárazását is, hogy az alkalmazás offline állapotban működjön, vagy ne befolyásolja a lassú hálózati kapcsolat.
- Mutasd az előrehaladási UI-t, ha a UI adatokra vár.
- Legyen óvatos az olyan alkalmazástervekkel, amelyek a konfigurációs fájlok vagy a kód által dinamikusan generált felhasználói felület sok elemzését foglalják magukban.
Elemszám csökkentése
Az XAML-alkalmazások indítási teljesítménye közvetlenül korrelál az indítás során létrehozott elemek számával. Minél kevesebb elemet hoz létre, annál kevesebb időt vesz igénybe az alkalmazás elindítása. Durva teljesítménytesztként fontolja meg, hogy az egyes elemek létrehozása 1 ms-t vesz igénybe.
- Az elemek vezérlőiben használt sablonok lehetnek a legnagyobb hatással, mivel többször ismétlődnek. Lásd: ListView és GridView felhasználói felület optimalizálása.
- A UserControls és a vezérlősablonok ki vannak bontva, ezért ezeket is figyelembe kell venni.
- Ha olyan XAML-t hoz létre, amely nem jelenik meg a képernyőn, akkor meg kell indokolnia, hogy ezeket az XAML-elemeket létre kell-e hozni az indítás során.
A Visual Studio Élő vizuális fa ablaka a fa minden csomópontjának gyermekelem-számát jeleníti meg.
Halasztás használata. Egy elem összecsukása vagy átlátszatlansága 0 értékre állítása nem akadályozza meg az elem létrehozását. A x:Load vagy x:DeferLoadStrategy használatával késleltetheti egy felhasználói felület betöltését, és szükség esetén betöltheti azt. Ez egy jó módja annak, hogy késleltetni tudja az indítás során nem látható felhasználói felület feldolgozását, hogy szükség esetén vagy késleltetett logika részeként betölthesse. A betöltés aktiválásához csak meg kell hívni az elemet a FindName paranccsal. Példa és további információ : x:Load attribútum és x:DeferLoadStrategy attribútum.
Virtualizálás. Ha lista- vagy ismétlőtartalma van a felhasználói felületen, akkor ajánlott felhasználói felületi virtualizálást használnia. Ha a lista felhasználói felülete nem virtualizálva van, akkor az összes elem létrehozásának költségeit előre kell fizetnie, és ez lelassíthatja az indítást. Lásd: ListView és GridView felhasználói felület optimalizálása.
Az alkalmazás teljesítménye nem csak a nyers teljesítményről szól; az észlelésről is szól. A műveletek sorrendjének módosítása oly módon, hogy először a vizuális elemek jelenjenek meg, gyakran azt az érzést kelti a felhasználóban, hogy az alkalmazás gyorsabban működik. A felhasználók úgy vélik, hogy az alkalmazás betöltve van, amikor a tartalom a képernyőn van. Az alkalmazásoknak általában több dolgot kell elvégeznie az indítás során, és nem minden munka szükséges a felhasználói felület létrehozásához, ezért ezeket a darabokat késleltetni vagy rangsorolni kell alacsonyabban, mint a felhasználói felület.
Ez a cikk az első keretről szól, amely az animáció és a videó terminológiájából származik, és annak mértéke, hogy mennyi ideig tart, amíg a végfelhasználó meg nem látja a tartalmat.
Az indítási észlelés javítása
Használjuk egy egyszerű online játék példáját, hogy azonosítsuk az indítás egyes fázisait és a különböző technikákat, hogy a felhasználó visszajelzést kapjon a folyamat során.
Az első fázisban elindul a folyamat, és az alkalmazás létrehozza annak ablakát. Ez idő alatt a felhasználó még nem látta az alkalmazás saját tartalmát. A cél az, hogy gyorsan egy minimális erőforrásigényű ablakot jelenítsen meg a képernyőn.
A második fázis magában foglalja a játék szempontjából kritikus struktúrák létrehozását és inicializálását. Ha az alkalmazás gyorsan létrehozhatja a kezdeti felhasználói felületet az indításkor elérhető adatokkal, akkor ez a fázis triviális, és azonnal megjelenítheti a felhasználói felületet. Ellenkező esetben az alkalmazás inicializálása közben jelenítsen meg egy egyszerű betöltési lapot.
Az, hogy a betöltési oldal hogyan néz ki, az Ön feladata; ez lehet olyan egyszerű, mint egy folyamatjelző sáv vagy egy folyamatgyűrű megjelenítése. A lényeg az, hogy az alkalmazás azt jelzi, hogy működik, mielőtt teljesen rugalmassá válik. A játék esetében a kezdeti képernyő megköveteli, hogy bizonyos képek és hangok betöltve legyenek a lemezről a memóriába. Ezek a feladatok időt vesznek igénybe, így az alkalmazás a felhasználót a játék témájához kapcsolódó egyszerű animációval rendelkező betöltési oldal megjelenítésével tájékoztatja.
A harmadik szakasz azután kezdődik, hogy a játék minimális információkészlettel rendelkezik egy interaktív felhasználói felület létrehozásához, amely felváltja a betöltési oldalt. Ezen a ponton az online játék számára az egyetlen elérhető információ lehet az alkalmazás által a lemezről betöltött tartalom. A játék elegendő tartalommal érkezhet, hogy létrehozzon egy interaktív felhasználói felületet, de mivel ez egy online játék, nem lesz teljesen működőképes, amíg nem csatlakozik az internethez, és le nem tölt néhány további információt. Amíg nem rendelkezik az összes szükséges információval, a felhasználó használhatja a felhasználói felületet, de a webes további adatokat igénylő funkcióknak visszajelzést kell adniuk arról, hogy a tartalom még betöltődik. Eltarthat egy ideig, amíg egy alkalmazás teljesen működőképessé válik, ezért fontos, hogy a funkciók a lehető leghamarabb elérhetővé váljanak.
Most, hogy azonosítottuk az online játék indítási három szakaszát, kapcsoljuk össze őket a tényleges kóddal.
1. és 2. fázis
Az alkalmazás konstruktorával csak az alkalmazás szempontjából kritikus adatstruktúrákat inicializálhatja. Koncentráljon OnLaunched az első ablak gyors létrehozására, az egyszerűsített tartalom hozzárendelésére és az ablak aktiválására, hogy az alkalmazás azonnal visszajelzést jelenítsen meg.
public partial class App : Application
{
public static Window MainWindow { get; private set; } = null!;
protected override void OnLaunched(LaunchActivatedEventArgs args)
{
base.OnLaunched(args);
MainWindow = new MainWindow();
MainWindow.Content = new LoadingPage();
MainWindow.Activate();
_ = InitializeAsync();
}
private async Task InitializeAsync()
{
// Asynchronously restore state and load the minimum data needed
// to create the first interactive UI.
await LoadInitialDataAsync();
MainWindow.Content = new GameHomePage();
}
private static Task LoadInitialDataAsync()
{
// Download data to populate the initial UI.
return Task.CompletedTask;
}
}
Az OnLaunched egyik legfontosabb feladata egy felhasználói felület létrehozása, hozzárendelése a Window.Content-hez, majd a Window.Activate hívása. Ha több aktiválási folyamatra van szüksége, tartsa meg ugyanazt az elvet: gyorsan jelenítsen meg könnyű tartalmakat, és helyezze át a költséges munkát a kritikus indítási útvonalról.
Azok az alkalmazások, amelyek indításkor megjelenítenek egy betöltési lapot, megkezdhetik a fő felhasználói felület létrehozását a háttérben. Az elem létrehozása után a FrameworkElement.Loaded esemény következik be. Az eseménykezelőben lecserélheti az ablak tartalmát, amely jelenleg a betöltési képernyő, az újonnan létrehozott kezdőlapra.
Kritikus fontosságú, hogy egy hosszabb inicializálási időszakkal rendelkező alkalmazás betöltési lapot jelenítsen meg. Amellett, hogy visszajelzést ad az indítási folyamatról, az ablakot gyorsan aktiválni kell, hogy a felhasználók lássák, hogy az alkalmazás halad.
partial class GameHomePage : Page
{
public GameHomePage()
{
InitializeComponent();
// Add a handler to be called when the home page has been loaded.
Loaded += GameHomePageLoaded;
// Load the minimal amount of image and sound data from disk necessary
// to create the home page.
}
private void GameHomePageLoaded(object sender, RoutedEventArgs e)
{
// Set the content of the main window to the home page now that it's
// ready to be displayed.
App.MainWindow.Content = this;
}
}
3. fázis
Csak azért, mert az alkalmazás megjelenítette a felhasználói felületet, még nem jelenti azt, hogy teljesen használatra kész. A játék esetében a felhasználói felület helyőrzőkkel jelenik meg az olyan funkciók esetében, amelyek az internetről származó adatokat igényelnek. Ezen a ponton a játék letölti a további adatokat, amelyek szükségesek ahhoz, hogy az alkalmazás teljesen működőképes legyen, és fokozatosan lehetővé tegye a funkciókat az adatok beszerzésekor.
Előfordulhat, hogy az indításhoz szükséges tartalom nagy része az alkalmazással együtt csomagolható. Ez történik egy egyszerű játéknál. Ez elég egyszerűvé teszi az indítási folyamatot. De sok programnak, például a hírolvasóknak és a fotómegjelenítőknek, a webről kell információkat lekérniük ahhoz, hogy működőképesek legyenek. Ezek az adatok nagy méretűek lehetnek, és a letöltés hosszú időt vehet igénybe. Az, hogy az alkalmazás hogyan szerzi be ezeket az adatokat az indítás során, nagy hatással lehet az észlelt teljesítményre.
Ha egy alkalmazás az indítás első vagy második fázisában egy teljes adatkészletet próbált letölteni, akkor túl sokáig jeleníthet meg betöltési lapot. Úgy tűnik, hogy az alkalmazás összeomlott. Javasoljuk, hogy egy alkalmazás töltse le a 2. fázisban helyőrző elemekkel rendelkező interaktív felhasználói felület megjelenítéséhez szükséges minimális adatmennyiséget, majd a 3. fázisban fokozatosan töltse be a helyőrző elemeket lecserélő adatokat. Az adatok kezeléséről további információt a ListView és a GridView optimalizálása című témakörben talál.
Az, hogy egy alkalmazás pontosan hogyan reagál az indítás egyes fázisaira, teljesen önön múlik, de a lehető legtöbb visszajelzést nyújtva a felhasználónak az egyszerű kezdeti felhasználói felület, a képernyők betöltése és a progresszív adatbetöltés révén az alkalmazás gyorsabban érzi magát.
Kezelt assemblyk minimalizálása az indítási útvonalon
Az újrahasználható kód gyakran a projektben található modulok (DLL-ek) formájában jelenik meg. Ezeknek a moduloknak a betöltése a lemezhez való hozzáférést igényli, és költségeik összeadódhatnak. Ez a legnagyobb hatással van a hideg indításra, de a meleg indításra is hatással lehet. A .NET-alkalmazásokban a CLR megpróbálja a lehető legnagyobb mértékben késleltetni a költségeket az assemblyk igény szerinti betöltésével. Vagyis a CLR nem tölt be modult, amíg egy végrehajtott metódus nem hivatkozik rá. Ezért csak olyan szerelvényekre hivatkozzon, amelyek szükségesek az alkalmazás indítási kódban való elindításához, hogy a CLR ne töltsön be felesleges modulokat. Ha az indítási útvonal nem használt kódútvonalai szükségtelen hivatkozásokkal rendelkeznek, helyezze át ezeket a kódútvonalakat más módszerekre a szükségtelen terhelés elkerülése érdekében.
A modulterhelések csökkentésének másik módja az alkalmazásmodulok kombinálása. Egy nagy szerelvény betöltése általában kevesebb időt vesz igénybe, mint két kisebb szerelvény betöltése. Ez nem mindig lehetséges, és csak akkor érdemes egyesíteni a modulokat, ha az nem tesz lényeges különbséget a fejlesztői hatékonyság vagy a kód újrafelhasználhatósága szempontjából. Az olyan eszközök, mint a PerfView vagy a Windows Teljesítményelemző (WPA) segítségével megtudhatja , hogy mely modulok töltődnek be indításkor.
Intelligens webes kérések létrehozása
Jelentősen javíthatja az alkalmazások betöltési idejét, ha helyileg csomagolja be annak tartalmát, beleértve az XAML-t, a képeket és az alkalmazás számára fontos egyéb fájlokat. A lemezműveletek gyorsabbak, mint a hálózati műveletek. Ha egy alkalmazásnak inicializáláskor szüksége van egy adott fájlra, csökkentheti az általános indítási időt úgy, hogy a távoli kiszolgálóról való lekérés helyett lemezről tölti be.
Napló- és gyorsítótárlapok hatékonyan
A Frame vezérlő navigációs funkciókat biztosít. Navigációt kínál egy lapra (Navigate metódusra), a navigációs naplózásra (BackStack és ForwardStack tulajdonságokra és GoForwardGoBack metódusokra), a lap gyorsítótárazására (Page.NavigationCacheMode), valamint a szerializáció támogatására (GetNavigationState metódus).
A Frame teljesítmény, amire érdemes odafigyelni, elsősorban a naplózásra és a lap gyorsítótárazására vonatkozik.
Keretnaplózás. Amikor egy olyan oldalra lép, amely tartalmazza Frame.Navigate, hozzáadnak egy PageStackEntry az aktuális oldalról a Frame.BackStack gyűjteménybe.
PageStackEntry viszonylag kicsi, de nincs beépített korlát a BackStack gyűjtemény méretére. Lehetséges, hogy egy felhasználó egy ciklusban navigálhat, és határozatlan ideig növelheti ezt a gyűjteményt.
A PageStackEntry tartalmazza azt a paramétert is, amit a Frame.Navigate metódusnak átadtak. Javasoljuk, hogy ez a paraméter egy primitív szerializálható típus legyen, például egy int vagy string, hogy lehetővé tegye a Frame.GetNavigationState metódus működését. Ez a paraméter azonban hivatkozhat egy olyan objektumra, amely nagyobb mennyiségű munkakészletet vagy más erőforrást tartalmaz, így minden BackStack bejegyzés ennél sokkal drágább. Használhat például paraméterként egy StorageFile paramétert, ezért a BackStack fájlok határozatlan ideig nyitva maradhatnak.
Ezért javasoljuk, hogy tartsa a navigációs paramétereket kicsiben, és korlátozza a méretét BackStack. Ez BackStack egy standard gyűjtemény a C#-ban, így egyszerűen levágható a bejegyzések eltávolításával.
Lap gyorsítótárazása. Ha a metódussal Frame.Navigate egy lapra lép, a rendszer alapértelmezés szerint egy új példányt hoz létre. Hasonlóképpen, ha a Frame.GoBack segítségével visszanavigál az előző oldalra, az előző oldal egy új példánya lesz lefoglalva.
Frame opcionális lapgyorsítótárat is kínál, amely elkerüli ezeket az instanciákat. Ha be szeretne helyezni egy lapot a gyorsítótárba, használja a tulajdonságot Page.NavigationCacheMode . Ha ezt a módot Required értékre állítja, az a lap gyorsítótárazását kényszeríti, míg ha Enabled értékre állítja, az lehetővé teszi a gyorsítótárazást. Alapértelmezés szerint a gyorsítótár mérete 10 oldal, de ezt felül lehet bírálni a Frame.CacheSize tulajdonsággal. Minden Required oldal gyorsítótárazva van, és ha kevesebb CacheSize szükséges oldal van, akkor Enabled oldal is gyorsítótárazható.
Az oldal gyorsítótárazása javíthatja a teljesítményt azáltal, hogy elkerüli a példányosításokat, és ezáltal javítja a navigációs teljesítményt. Az oldal gyorsítótárazása ronthatja a teljesítményt a túlzott gyorsítótárazás miatt, amely így hatással van a futó készletre.
Ezért javasoljuk, hogy az alkalmazásnak megfelelő oldal gyorsítótárazást használjon. Tegyük fel például, hogy van egy olyan alkalmazása, amely egy elemlistát jelenít meg, Frameés amikor kijelöl egy elemet, az az elem részletes lapjára navigál. A listaoldalt valószínűleg gyorsítótárra kell állítani. Ha a részletező oldal minden elemnél megegyezik, akkor valószínűleg gyorsítótárazva kellene lennie. Ha azonban a részletoldal heterogénebb, akkor jobb lehet kikapcsolni a gyorsítótárazást.
Windows developer