Firebase Performance Monitoring ile yükleme süresini ve ekran oluşturmayı ölçün

1. Giriş

Son Güncelleme Tarihi: 11.03.2021

Görüntülemelerin performansını neden ölçmemiz gerekiyor?

Görünümler, Android uygulamalarının kullanıcı deneyimini doğrudan etkileyen önemli bir parçasıdır. Örneğin, Etkinliğiniz veya Parçanız, kullanıcıların etkileşimde bulunduğu Görünüm bileşenlerini barındıran kullanıcı arayüzünü içerir. Kullanıcılar, arayüz tamamen ekrana çizilinceye kadar kullanıcı arayüzünün tüm içeriğini göremez. Yavaş ve donmuş ekranlar, kullanıcıların uygulamanızla etkileşimini doğrudan olumsuz etkiler ve kötü bir kullanıcı deneyimi oluşturur.

Firebase Performance Monitoring, bu performans metriklerini kullanıma hazır olarak sunmuyor mu?

Firebase Performance Monitoring, uygulamanızın başlangıç zamanı (ör. yalnızca ilk Etkinliğiniz için yükleme süresi) ve ekran oluşturma performansı (ör. Etkinlikler için yavaş ve donmuş kareler (Parçalar için değil) gibi bazı performans verilerini kullanıma hazır şekilde otomatik olarak yakalar. Ancak sektör uygulamalarında genellikle çok fazla Etkinlik bulunmaz. Bunun yerine bir Etkinlik ve birden fazla Parça bulunur. Ayrıca birçok uygulama, daha karmaşık kullanım alanları için genellikle kendi özel görünümlerini uygular. Bu nedenle, uygulamanızda özel kod izlerini kullanarak hem etkinliklerin hem de parçaların yükleme süresini ve ekran oluşturma performansını nasıl ölçeceğinizi anlamak genellikle yararlıdır. Özel Görünüm bileşenlerinin performansını ölçmek için bu codelab'i kolayca genişletebilirsiniz.

Neler öğreneceksiniz?

  • Firebase Performance Monitoring'i Android uygulamalarına ekleme
  • Bir etkinliğin veya parçanın yüklenmesini anlama
  • Bir etkinliğin veya parçanın yükleme süresini ölçmek için özel kod izlerini kullanma
  • Ekran Oluşturmayı ve Yavaş/Donmuş karenin ne olduğunu anlama
  • Yavaş/Donmuş ekranları kaydetmek için metriklerle özel kod izlerini ölçme
  • Toplanan metrikleri Firebase konsolunda görüntüleme

Gerekenler

  • Android Studio 4.0 veya sonraki sürümler
  • Android cihaz/emülatör
  • Java sürüm 8 veya üstü

2. Kurulum

Kodu alma

Bu codelab için örnek kodu klonlamak amacıyla aşağıdaki komutları çalıştırın. Bu işlem, makinenizde codelab-measure-android-view-performance adında bir klasör oluşturur:

$ git clone https://github.com/FirebaseExtended/codelab-measure-android-view-performance.git
$ cd codelab-measure-android-view-performance

Makinenizde Git yoksa kodu doğrudan GitHub'dan da indirebilirsiniz.

measure-view-performance-start projesini Android Studio'ya aktarın. Büyük olasılıkla bazı derleme hataları veya eksik bir google-services.json dosyası ile ilgili bir uyarı görürsünüz. Bu sorunu, bu adımın bir sonraki bölümünde düzelteceğiz.

Bu codelab'de, Android uygulamamızı bir Firebase projesine kaydetmek ve gerekli Firebase yapılandırma dosyalarını, eklentilerini ve bağımlılıklarını Android projemize eklemek için Firebase Asistan eklentisini kullanacağız. Tüm bunları Android Studio'dan yapacağız.

Uygulamanızı Firebase'e bağlama

  1. Android Studio/Yardım'a gidin > Android Studio ve Firebase Asistan'ın en son sürümlerini kullandığınızdan emin olmak için güncellemeleri kontrol edin.
  2. Araçlar > Asistan bölmesini açmak için Firebase.

e791bed0999db1e0.png

  1. Uygulamanıza eklemek için Performance Monitoring'i seçin ve ardından Get started with Performance Monitoring'i (Performans İzleme ile kullanmaya başlayın) tıklayın.
  2. Android projenizi Firebase'e bağlamak için Firebase'e bağlan'ı tıklayın (bu işlem, tarayıcınızda Firebase konsolunu açar).
  3. Firebase konsolunda Proje ekle'yi tıklayın ve ardından bir Firebase proje adı girin (zaten bir Firebase projeniz varsa bunun yerine mevcut projeyi seçebilirsiniz). Firebase projesi ve yeni bir Firebase uygulaması oluşturmak için Devam'ı tıklayın ve şartları kabul edin.
  4. Ardından, yeni Firebase Uygulamanızı Android Studio projenize bağlamanız için bir iletişim kutusu göreceksiniz.

42c498d28ead2b77.png

  1. Android Studio'ya döndüğünüzde Asistan bölmesinde uygulamanızın Firebase'e bağlandığına dair onay görürsünüz.

dda8bdd9488167a0.png

Uygulamanıza Performance Monitoring'i ekleyin

Android Studio'daki Asistan bölmesinde Uygulamanıza Performance Monitoring ekleyin'i tıklayın.

Değişiklikleri Kabul Et iletişim kutusunu göreceksiniz. Bu iletişim kutusundan sonra Android Studio, gerekli tüm bağımlılıkların eklendiğinden emin olmak için uygulamanızı senkronize etmelidir.

9b58145acc4be030.png

Son olarak, Android Studio'daki Asistan bölmesinde tüm bağımlılıkların doğru şekilde ayarlandığını belirten başarı mesajını göreceksiniz.

aa0d46fc944e0c0b.png

Ek bir adım olarak "(İsteğe bağlı) Hata ayıklama günlük kaydını etkinleştirme" adımındaki talimatları uygulayarak hata ayıklama günlük kaydını etkinleştirin. Aynı talimatlar, herkese açık belgelerde de mevcuttur.

3. Uygulamayı çalıştırın

Uygulamanızı Performance Monitoring SDK'sı ile başarılı bir şekilde entegre ettiyseniz projenin şimdi derlenmesi gerekir. Android Studio'da Çalıştır'ı tıklayın > Bağlı Android cihazınızda/emülatörünüzde uygulamayı geliştirip çalıştırmak için "uygulamayı" çalıştırın.

Uygulamada sizi ilgili bir Etkinlik ve Parçaya yönlendiren iki düğme vardır. Örneğin:

410d8686b4f45c33.png

Bu codelab'in sonraki adımlarında, Etkinliğinizin veya Parçanızın yükleme süresini ve ekran oluşturma performansını nasıl ölçeceğinizi öğreneceksiniz.

4. Bir etkinliğin veya parçanın yüklenmesini anlama

Bu adımda, bir Etkinlik veya Parçanın yüklenmesi sırasında sistemin ne yaptığını öğreneceğiz.

Bir etkinliğin yüklenmesini anlama

Bir Etkinlik için yükleme süresi, Etkinlik nesnesinin oluşturulmasından İlk Kare tamamen ekrana çizilinceye kadar geçen süre olarak tanımlanır (kullanıcınız, Etkinlik için kullanıcı arayüzünün tamamını ilk kez görecektir.). Uygulamanızın tamamen çizilip çizilmediğini ölçmek için reportFullyDrawn() yöntemini kullanarak uygulamanın başlatılması ile tüm kaynakların tamamen gösterilmesi ve hiyerarşileri görüntüleme arasında geçen süreyi ölçebilirsiniz.

Genel olarak, uygulamanız startActivity(Intent) çağırdığında sistem aşağıdaki işlemleri otomatik olarak gerçekleştirir. Her işlemin tamamlanması zaman alır. Bu da, Etkinliği oluşturma ile kullanıcının ekranında Etkinlik kullanıcı arayüzünü görmesi arasında geçen süreyi artırır.

c20d14b151549937.png

Bir Parçanın yüklenmesini anlama

Etkinliğe benzer şekilde, bir Parçanın yükleme süresi, Parçanın ana makine Etkinliğine eklenmesinden başlayıp Parça Görünümü'nün İlk Kare'sinin ekranda tamamen çizilinceye kadar geçen süredir.

5. Bir etkinliğin yükleme süresini ölçme

İlk karedeki gecikmeler kötü bir kullanıcı deneyimine yol açabilir. Bu nedenle, kullanıcılarınızın ilk yüklemede ne kadar gecikme yaşadığını anlamanız önemlidir. Bu yükleme süresini ölçmek için özel kod izleme aracı kullanabilirsiniz:

  1. Etkinlik nesnesi oluşturulur oluşturulmaz Etkinlik sınıfında özel kod izlemeyi (TestActivity-LoadTime adlı) başlatın.

TestActivity.Java

public class TestActivity extends AppCompatActivity {   
    // TODO (1): Start trace recording as soon as the Activity object is created.
    private final Trace viewLoadTrace = FirebasePerformance.startTrace("TestActivity-LoadTime");

    // ...

}
  1. onCreate()Geri çağırmayı geçersiz kılın ve setContentView()yöntemi ile eklenen görünümü alın.
@Override     
public void onCreate(Bundle savedInstanceState) {    
    super.onCreate(savedInstanceState);          

    // Current Activity's main View (as defined in the layout xml file) is inflated after this            
    setContentView(R.layout.activity_test);          

    // ...

    // TODO (2): Get the View added by Activity's setContentView() method.         
    View mainView = findViewById(android.R.id.content);     

    // ...
}
  1. İki geri çağırma özelliği olan bir FistDrawListener uygulamasını ekledik: onDrawingStart() ve onDrawingFinish() (FirstDrawListener ve performansını nelerin etkileyebileceği ile ilgili daha fazla ayrıntı için aşağıda yer alan bir sonraki bölüme bakın). Etkinlik onCreate() geri çağırmasının sonuna FirstDrawListener kaydedin. Geri çağırmada viewLoadTraceonDrawingFinish() işlemini durdurmanız gerekir.

TestActivity.Java

    // TODO (3): Register the callback to listen for first frame rendering (see
    //  "OnFirstDrawCallback" in FirstDrawListener) and stop the trace when View drawing is
    //  finished.
    FirstDrawListener.registerFirstDrawListener(mainView, new FirstDrawListener.OnFirstDrawCallback() {              
        @Override             
        public void onDrawingStart() {       
          // In practice you can also record this event separately
        }

        @Override             
        public void onDrawingFinish() {
            // This is when the Activity UI is completely drawn on the screen
            viewLoadTrace.stop();             
        }         
    });
  1. Uygulamayı yeniden çalıştırın. Ardından, logcat'i "Logging trace metriği" ile filtreleyin. LOAD ACTIVITY düğmesine dokunun ve aşağıdakine benzer günlükleri arayın:
I/FirebasePerformance: Logging trace metric: TestActivity-LoadTime (duration: XXXms)

🎉 Tebrikler! Bir etkinliğin yükleme süresini başarıyla ölçtünüz ve bu verileri Firebase Performance Monitoring'e bildirdiniz. Kaydedilen metriği, bu codelab'in ilerleyen bölümlerinde Firebase konsolunda göreceğiz.

FirstDrawListener'ın Amacı

Yukarıdaki bölümde bir FirstDrawListener kaydettik. FirstDrawListener işlevinin amacı, ilk karenin ne zaman çizime başladığını ve çizimi tamamladığını ölçmektir.

ViewTreeObserver.OnDrawListener yöntemini uygular ve Görünüm ağacı çizilmek üzereyken çağrılan onDraw() geri çağırmasını geçersiz kılar. Daha sonra, sonucu sarmalayarak iki yardımcı program geri çağırması sağlar onDrawingStart() ve onDrawingFinish().

FirstDrawListener kodunun tamamını bu codelab'in kaynak kodunda bulabilirsiniz.

6. Bir Parçanın yükleme süresini ölçme

Bir Parçanın yükleme süresini ölçmek, bir Etkinlik için ölçme şeklimize benzer ancak bazı küçük farklılıklar içerir. Burada da özel kod izleme yöntemini kullanırız:

  1. onAttach() geri çağırmasını geçersiz kılın ve fragmentLoadTrace kaydınızı kaydetmeye başlayın. Bu izini Test-Fragment-LoadTime olarak adlandıracağız.

Önceki adımda açıklandığı gibi, Parça nesnesi istediğiniz zaman oluşturulabilir, ancak yalnızca ana makine Etkinliğine bağlı olduğunda etkin hale gelir.

TestFragment.Java

public class TestFragment extends Fragment {

   // TODO (1): Declare the Trace variable.
   private Trace fragmentLoadTrace;

   @Override
   public void onAttach(@NonNull Context context) {
       super.onAttach(context);

       // TODO (2): Start trace recording as soon as the Fragment is attached to its host Activity.
       fragmentLoadTrace = FirebasePerformance.startTrace("TestFragment-LoadTime");
   }
  1. FirstDrawListener öğesini onViewCreated()geri çağırmaya kaydedin. Ardından, Etkinlik örneğine benzer şekilde onDrawingFinish() öğesindeki izi durdurun.

TestFragment.Java

@Override
public void onViewCreated(@NonNull View mainView, Bundle savedInstanceState) {
   super.onViewCreated(mainView, savedInstanceState);

   // ...

   // TODO (3): Register the callback to listen for first frame rendering (see
   //  "OnFirstDrawCallback" in FirstDrawListener) and stop the trace when view drawing is
   //  finished.
   FirstDrawListener.registerFirstDrawListener(mainView, new FirstDrawListener.OnFirstDrawCallback() {

       @Override
       public void onDrawingStart() {
           // In practice you can also record this event separately
       }

       @Override
       public void onDrawingFinish() {
           // This is when the Fragment UI is completely drawn on the screen
           fragmentLoadTrace.stop();
       }
   });
  1. Uygulamayı yeniden çalıştırın. Ardından, logcat'i "Logging trace metriği" ile filtreleyin. LOAD FRAGMENT düğmesine dokunun ve aşağıdakine benzer günlükleri arayın:
I/FirebasePerformance: Logging trace metric: TestFragment-LoadTime (duration: XXXms)

🎉 Tebrikler! Bir Parçanın yükleme süresini başarıyla ölçtünüz ve bu verileri Firebase Performance Monitoring'e bildirdiniz. Kaydedilen metriği, bu codelab'in ilerleyen bölümlerinde Firebase konsolunda göreceğiz.

7. Ekran Oluşturmayı ve Yavaş/Donmuş karenin ne olduğunu anlama

Kullanıcı Arayüzü Oluşturma, uygulamanızdan bir kare oluşturma ve bunu ekranda görüntüleme işlemidir. Kullanıcıların uygulamanızla sorunsuz bir etkileşim kurabilmesi için uygulamanız, kareleri 16 ms.den düşük bir hızda oluşturarak saniyede 60 kareye ulaşmalıdır ( neden 60 fps?). Uygulamanızın yavaş kullanıcı arayüzü oluşturma sorunu varsa sistem, kareleri atlamaya zorlanır ve kullanıcı uygulamanızda takılmayı algılar. Buna jank diyoruz.

Benzer şekilde donmuş kareler de oluşturulması 700 ms'den uzun süren kullanıcı arayüzü kareleridir. Uygulamanız takılmış gibi göründüğünden ve kare oluşturulurken neredeyse tam bir saniye boyunca kullanıcı girişine yanıt vermiyor gibi bu gecikme bir sorun teşkil eder.

8. Bir parçanın Yavaş/Donmuş karelerini ölçme

Firebase Performance Monitoring, bir Etkinlik için yavaş/donmuş kareleri otomatik olarak yakalar (ancak yalnızca Donanım Hızlandırmalı). Ancak bu özellik şu anda Parçalar için kullanılamamaktadır. Bir Parçanın yavaş/donmuş kareleri, Parçanın yaşam döngüsündeki onFragmentAttached() ile onFragmentDetached() geri çağırmaları arasında tüm Etkinlikteki yavaş/donmuş kareler olarak tanımlanır.

AppStateMonitor sınıfından (Etkinlik için ekran izlemelerini kaydetmekten sorumlu Performance Monitoring SDK'sının bir parçasıdır) motivasyonumuzdan yola çıkarak ScreenTrace sınıfını (bu codelab kaynak kodu deposunun bir parçasıdır) uyguladık. ScreenTrace sınıfı, yavaş/donmuş kareleri yakalamak için Etkinliğin FragmentManager yaşam döngüsü geri çağırmasına bağlanabilir. Bu sınıf iki herkese açık API sağlar:

  • recordScreenTrace(): Ekran izi kaydetmeye başlar
  • sendScreenTrace(): Ekran izleme kaydını durdurur ve Toplam, Yavaş ve Donmuş kare sayılarını günlüğe kaydetmek için özel metrikler ekler.

Bu özel metrikler eklendiğinde, Parçalara ait ekran izleri, Etkinliklerin ekran izleri gibi işlenebilir ve Firebase konsolunun Performans kontrol panelinde diğer ekran oluşturma izleri ile birlikte gösterilebilir.

Parçanız için ekran izlerini nasıl günlüğe kaydedeceğiniz aşağıda açıklanmıştır:

  1. Etkinliğinizde, Parçayı barındıran ScreenTrace sınıfını başlatın.

MainActivity.Java

// Declare the Fragment tag
private static final String FRAGMENT_TAG = TestFragment.class.getSimpleName();

// TODO (1): Declare the ScreenTrace variable.
private ScreenTrace screenTrace;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // TODO (2): Initialize the ScreenTrace variable.
    screenTrace = new ScreenTrace(this, FRAGMENT_TAG);

    // ...
}
  1. Parçanızı yüklediğinizde FragmentLifecycleCallbacks için kaydolun ve onFragmentAttached() ile onFragmentDetached()geri çağırmaları geçersiz kılın. Bunu sizin için yaptık. onFragmentAttached() geri çağırmasında ekran izlerini kaydetmeye başlamanız ve onFragmentDetached() geri çağırmasında kaydı durdurmanız gerekiyor.

MainActivity.Java

private final FragmentManager.FragmentLifecycleCallbacks fragmentLifecycleCallbacks =
       new FragmentManager.FragmentLifecycleCallbacks() {

           @Override
           public void onFragmentAttached(@NonNull FragmentManager fm, @NonNull Fragment f, @NonNull Context context) {
               super.onFragmentAttached(fm, f, context);

               // TODO (3): Start recording the screen traces as soon as the Fragment is
               //  attached to its host Activity.
               if (FRAGMENT_TAG.equals(f.getTag()) && screenTrace.isScreenTraceSupported()) {
                   screenTrace.recordScreenTrace();
               }
           }

           @Override
           public void onFragmentDetached(@NonNull FragmentManager fm, @NonNull Fragment f) {
               super.onFragmentDetached(fm, f);

               // TODO (4): Stop recording the screen traces as soon as the Fragment is
               //  detached from its host Activity.
               if (FRAGMENT_TAG.equals(f.getTag()) && screenTrace.isScreenTraceSupported()) {
                   screenTrace.sendScreenTrace();
               }

               // Unregister Fragment lifecycle callbacks after the Fragment is detached
               fm.unregisterFragmentLifecycleCallbacks(fragmentLifecycleCallbacks);
           }
       };
  1. Uygulamayı yeniden çalıştırın. Ardından LOAD FRAGMENT düğmesine dokunun. Birkaç saniye bekleyin, ardından alt gezinme çubuğundaki back button simgesini tıklayın.

Logcat'i "Logging trace metriği" ile filtreleyin ve aşağıdakine benzer günlükleri bulun:

I/FirebasePerformance: Logging trace metric: _st_MainActivity-TestFragment (duration: XXXms)

Logcat'i "FireperfViews" ile filtreleyin ve aşağıdakine benzer günlükleri bulun:

D/FireperfViews: sendScreenTrace MainActivity-TestFragment, name: _st_MainActivity-TestFragment, total_frames: XX, slow_frames: XX, frozen_frames: XX

🎉 Tebrikler! Bir parçanın Yavaş/Donmuş karelerini başarıyla ölçtünüz ve bu verileri Firebase Performance Monitoring'e bildirdiniz. Kaydedilen metrikleri bu codelab'in ilerleyen bölümlerinde Firebase konsolunda görüntüleyeceğiz.

9. Firebase konsolunda metrikleri kontrol edin

  1. İzlemeyle ilgili ayrıntılar sayfasını ziyaret etmek için logcat'te Firebase konsolu URL'sini tıklayın. ceb9d5ba51bb6e89.jpeg.

Alternatif olarak Firebase konsolunda, uygulamanızın bulunduğu projeyi seçin. Sol panelde Sürüm ve İzleme bölümünü ve ardından Performans'ı tıklayın.

  • Ana Kontrol paneli sekmesinde, izler tablosuna gidin ve Özel izler sekmesini tıklayın. Bu tabloda, daha önce eklediğimiz özel kod izlerini ve _app_start iz gibi bazı kullanıma hazır izleri görürsünüz.
  • İki özel kod izinizi (TestActivity-LoadTime ve TestFragment-LoadTime) bulun. Toplanan verilerle ilgili daha fazla ayrıntı görmek için, birisine ilişkin Süre'yi tıklayın.

a0d8455c5269a590.png

  1. Özel kod izlemenin ayrıntı sayfası, iz süresi (ölçülen yükleme süresi) hakkında bilgi gösterir.

5e92a307b7410d8b.png

  1. Özel ekran izinizin performans verilerini de görüntüleyebilirsiniz.
  • Ana Kontrol paneli sekmesine dönün, izler tablosuna gidin ve Ekran oluşturma sekmesini tıklayın. Bu tabloda, daha önce eklediğimiz özel ekran izlerinin yanı sıra MainActivity iz gibi kullanıma hazır ekran izlerini görürsünüz.
  • Özel ekran izlemenizi bulun (MainActivity-TestFragment). Yavaş oluşturma ve donmuş karelerle ilgili birleştirilmiş verileri görüntülemek için iz adını tıklayın.

ee7890c7e2c28740.png

10. Tebrikler

Tebrikler! Firebase Performance Monitoring'i kullanarak bir etkinliğin ve parçanın yükleme süresini ve ekran oluşturma performansını başarıyla ölçtünüz.

Yaptıklarınız

  • Firebase Performance Monitoring'i örnek bir uygulamaya entegre ettiniz
  • Görünüm yüklemenin yaşam döngüsünü artık biliyorsunuz
  • Özel kod izleri ekleyerek hem bir etkinliğin hem de bir parçanın yükleme süresini ölçtünüz
  • Özel metrikler içeren özel ekran izleri ekleyerek yavaş/donmuş kareler kaydettiniz

Sırada ne var?

Firebase Performance, uygulamanız için özel izleme dışında daha fazla performans ölçümü yöntemi sunar. Uygulama başlatma süresi, uygulama ön planda ve arka plandaki uygulama performans verilerini otomatik olarak ölçer. Bu metrikleri Firebase Konsolu'nda kontrol etmenizin zamanı geldi.

Ayrıca Firebase Performance, otomatik HTTP/S ağ isteği izleme özelliği de sunar. Bu sayede, tek bir satır kod yazmadan ağ isteklerini kolayca inceleyebilirsiniz. Uygulamanızdan bazı ağ istekleri göndermeyi deneyip Firebase konsolunda metrikleri bulabilir misiniz?

Bonus

Artık özel kod izlerini kullanarak Etkinliğinizin/Parçalarınızın yükleme süresini ve ekran oluşturma performansını nasıl ölçeceğinizi öğrendiğinize göre açık kaynaklı kod tabanımızı inceleyerek bu metrikleri uygulamanın parçası olan herhangi bir Etkinlik/Parça için kullanıma hazır hale getirip getiremeyeceğinizi kontrol edebilir misiniz? İsterseniz basın bültenini gönderebilirsiniz :-)

11. Bonus Öğrenme

Bir etkinliğin yüklenmesi sırasında neler olduğunu anlamak, uygulamanızın performans özelliklerini daha iyi anlamanıza yardımcı olur. Önceki bir adımda, bir Etkinliğin yüklenmesi sırasında ne olduğunu genel bir şekilde açıkladık, ancak aşağıdaki şemada her bir aşama çok daha ayrıntılı olarak açıklanmaktadır.

cd61c1495fad7961.png