Planowanie i mierzenie wydajności aplikacji

Użytkownicy oczekują, że ich aplikacje będą reagować, czuć się naturalnie, a nie opróżniać baterii. Technicznie wydajność jest wymaganiem niefunkcjonalnym, ale traktowanie wydajności jako funkcji pomaga spełnić oczekiwania użytkowników. Określ cele i pomiary wyników — są to kluczowe czynniki. Określ scenariusze krytyczne dla wydajności, zdefiniuj, co oznacza dobra wydajność, a następnie zmierz wcześnie i często w całym cyklu życia projektu, aby mieć pewność, że osiągniesz cele.

Określanie celów

Środowisko użytkownika to podstawowy sposób definiowania dobrej wydajności. Czas uruchamiania aplikacji może mieć wpływ na postrzeganie jej wydajności przez użytkownika. Użytkownik może uznać czas uruchamiania aplikacji krótszy niż jedna sekunda za doskonały, krótszy niż pięć sekund za dobry, a dłuższy niż pięć sekund za słaby.

Inne metryki mają mniej oczywisty wpływ na środowisko użytkownika, takie jak pamięć. Prawdopodobieństwo zamknięcia aplikacji, gdy jest wstrzymana lub nieaktywna, rośnie wraz z ilością pamięci używanej przez aktywną aplikację. Wysokie użycie pamięci obniża wydajność obsługi wszystkich aplikacji w systemie, dlatego cel zużycia pamięci jest rozsądny.

Ustaw początkowe cele, które są specyficzne i wymierne. Powinny one należeć do trzech kategorii:

  • Czas — czas potrzebny użytkownikom lub aplikacji na wykonywanie zadań
  • Płynność — szybkość i ciągłość, za pomocą której aplikacja ponownie rysuje się w odpowiedzi na interakcję użytkownika
  • Wydajność — jak dobrze aplikacja oszczędza zasoby systemowe, w tym zasilanie baterii

Time

Pomyśl o dopuszczalnych zakresach czasu ,który upłynął (klasy interakcji), aby użytkownicy ukończyli swoje zadania.

Klasa interakcji Postrzeganie przez użytkownika Ideal Maximum Examples
Szybko Minimalne zauważalne opóźnienie 100 ms 200 ms Wyświetl pasek aplikacji; naciśnij przycisk (pierwsza odpowiedź)
Typowe Szybkie, ale nie szybkie 300 ms 500 ms Zmień rozmiar; powiększenie semantyczne
Elastyczne Nie szybkie, ale reaguje szybko 500 ms 1 sekunda Przejdź do innej strony; wznawianie działania aplikacji
Launch Doświadczenie związane z konkurencją 1 sekunda 3 sekundy Uruchamianie aplikacji po raz pierwszy
Ciągły Nie czuje się już responsywny 500 ms 5 sekund Pobieranie pliku z Internetu
Niewoli Długi; użytkownik może przełączyć się gdzie indziej 500 ms 10 sekund Instalowanie wielu aplikacji ze Sklepu

Przypisz klasy interakcji do scenariuszy wydajności aplikacji. Dla każdego scenariusza przypisz punkt odniesienia w czasie aplikacji, obszar środowiska użytkownika i klasę interakcji.

Płynność

Konkretne, mierzalne cele dotyczące płynności Twojej aplikacji mogą obejmować:

  • Bez zakłóceń odświeżania ekranu (przycięć)
  • Animacje renderowane na 60 klatek na sekundę (FPS)
  • Gdy użytkownik przesuwa widok lub przewija, aplikacja wyświetla 3–6 stron zawartości na sekundę

Efficiency

Konkretne mierzalne cele wydajności aplikacji mogą obejmować:

  • Procent użycia procesora CPU aplikacji wynosi lub poniżej wartości docelowej, a użycie pamięci w MB wynosi lub poniżej wartości docelowej przez cały czas
  • Gdy aplikacja jest nieaktywna, użycie procesora CPU i pamięci jest minimalne
  • Aplikacja może być aktywnie używana przez docelową liczbę godzin zasilania baterii

Projektowanie aplikacji pod kątem wydajności

Użyj celów wydajności, aby wpłynąć na projekt aplikacji. Rozważ następujące aspekty:

Interfejs użytkownika

  • Zmaksymalizuj efektywność czasu analizowania i ładowania oraz wykorzystania pamięci dla każdej strony, optymalizując kod XAML. Opóźnij ładowanie interfejsu użytkownika i kodu, dopóki nie będą potrzebne.
  • Dla ListView i GridView spraw, aby wszystkie elementy miały ten sam rozmiar, i zastosuj jak najwięcej technik optymalizacji.
  • Zadeklaruj interfejs użytkownika w znacznikach, a nie konstruuj go w kodzie.
  • Opóźnij tworzenie elementów interfejsu użytkownika, dopóki użytkownik nie będzie ich potrzebował przy użyciu atrybutu x:Load .
  • Preferowane są przejścia motywów i animacje zamiast animacji opartych na scenorysie. Animacje oparte na scenorysach wymagają ciągłego odświeżania ekranu i utrzymują aktywność procesora CPU oraz potoku graficznego.
  • Załaduj obrazy o rozmiarze odpowiednim dla widoku, w którym je przedstawisz.

Procesor CPU, pamięć i moc

  • Planuj zadania o niższym priorytecie na wątkach o niższym priorytecie. Zobacz Programowanie asynchroniczne i klasę DispatcherQueue .
  • Zminimalizuj ślad pamięci aplikacji, zwalniając kosztowne zasoby (takie jak multimedia), gdy nie są potrzebne.
  • Unikaj wycieków pamięci, wyrejestrowując procedury obsługi zdarzeń i usuwając odwołania do elementów interfejsu użytkownika zawsze, gdy to możliwe.
  • Aby uzyskać wydajność baterii, zachowaj ostrożność przy sposobie sondowania danych, wykonywania zapytań dotyczących czujnika lub planowania pracy na procesorze, gdy jest bezczynny.

Dostęp do danych

  • Jeśli to możliwe, wstępnie pobierz zawartość.
  • Buforuj treści, których pobranie jest kosztowne.
  • W przypadku chybień pamięci podręcznej wyświetl symbol zastępczy interfejs użytkownika tak szybko, jak to możliwe, co wskazuje, że aplikacja nadal ładuje zawartość.

Instrument na potrzeby wydajności

Podczas opracowywania kodu dodaj kod, który rejestruje komunikaty i zdarzenia w określonych punktach podczas uruchamiania aplikacji. Później użyj narzędzi profilowania, takich jak Windows Performance Recorder i Windows Analizator wydajności (zarówno w Windows Performance Toolkit), aby utworzyć i wyświetlić raport dotyczący wydajności aplikacji.

System Windows udostępnia interfejsy API rejestrowania oparte na Event Tracing for Windows (ETW), które oferują bogate możliwości rejestrowania i śledzenia zdarzeń. Interfejsy API w przestrzeni nazw Windows.Foundation.Diagnostics obejmują klasy FileLoggingSession, LoggingActivity, LoggingChannel i LoggingSession.

// using Windows.Foundation.Diagnostics;

LoggingChannel myLoggingChannel = new LoggingChannel("MyLoggingChannel");
myLoggingChannel.LogMessage("Here's my logged message.", LoggingLevel.Information);

Aby rejestrować zdarzenia uruchamiania i zatrzymywania w danym okresie:

LoggingChannel myLoggingChannel = new LoggingChannel("MyLoggingChannel");
LoggingActivity myLoggingActivity;

using (myLoggingActivity = new LoggingActivity("MyLoggingActivity", myLoggingChannel))
{
    // A start event is logged when the activity begins.
    // Add code here to do something of interest.
}
// An end event is logged when the activity ends.

Testuj i mierz względem celów wydajnościowych

Użyj tych technik i narzędzi, aby sprawdzić, jak Twoja aplikacja wypada względem Twoich celów wydajnościowych:

  • Przetestuj różne konfiguracje sprzętowe, w tym komputery stacjonarne, laptopy, ultrabooki i tablety.
  • Przetestuj pod kątem szerokiej gamy rozmiarów ekranu. Szersze ekrany pokazują więcej zawartości, co może negatywnie wpłynąć na wydajność.
  • Wyeliminuj dowolną liczbę zmiennych testowych, jak to możliwe:
    • Wyłącz aplikacje w tle na urządzeniu testowym.
    • Skompiluj aplikację w konfiguracji wydania przed wdrożeniem jej na urządzeniu testowym.
    • Uruchom aplikację wiele razy, aby wyeliminować losowe zmienne testowania i zapewnić spójne pomiary.
  • Przetestuj pod kątem mniejszej dostępności zasilania. Urządzenia użytkowników mogą mieć znacznie mniejszą moc niż maszyna deweloperza.
  • Użyj kombinacji narzędzi, takich jak narzędzia diagnostyczne Visual Studio i Windows Analizator wydajności, aby zmierzyć wydajność aplikacji.

Reagowanie na wyniki testu wydajnościowego

Po przeanalizowaniu wyników testu wydajnościowego określ, czy są potrzebne jakieś zmiany:

  • Czy należy zmienić decyzje projektowe aplikacji lub zoptymalizować kod?
  • Czy należy dodać, usunąć lub zmienić instrumentację w kodzie?
  • Czy należy skorygować cele dotyczące wydajności?

Jeśli zmiany są potrzebne, wprowadź je i wróć do instrumentowania lub testowania.

Optimize

Zoptymalizuj tylko ścieżki kodu o znaczeniu krytycznym dla wydajności w aplikacji — te, w których spędzasz najwięcej czasu. Profilowanie informuje o tych obszarach. Często istnieje kompromis między dobrymi rozwiązaniami projektowymi i kodem, który wykonuje najwyższą optymalizację. Określanie priorytetów produktywności deweloperów i dobrego projektowania oprogramowania w obszarach, w których wydajność nie jest problemem.