יצירת פרופילים בסיסיים

יצירת פרופילים באופן אוטומטי לכל גרסה של האפליקציה באמצעות ספריית Jetpack Macrobenchmark ו-BaselineProfileRule. מומלץ להשתמש בגרסה com.android.tools.build:gradle:8.0.0 ומעלה, שכוללת שיפורים בבנייה כשמשתמשים בפרופילים בסיסיים.

אלה השלבים הכלליים ליצירת פרופיל בסיסי חדש:

  1. מגדירים את המודול Baseline Profile (פרופיל בסיסי).
  2. מגדירים את בדיקת JUnit שעוזרת ליצור פרופילים של Baseline.
  3. מוסיפים את חוויית המשתמש ההכרחית (CUJ) שרוצים לבצע לה אופטימיזציה.
  4. יוצרים את פרופיל ה-Baseline.

אחרי שיוצרים את פרופיל הבסיס, משווים אותו לביצועים של מכשיר פיזי כדי למדוד את שיפורי המהירות.

יצירת פרופיל בסיסי חדש באמצעות AGP בגרסה 8.2 ומעלה

הדרך הקלה ביותר ליצור פרופיל בסיסי חדש היא להשתמש בתבנית של מודול פרופיל בסיסי, שזמינה החל מ-Android Studio Iguana ומ-Android Gradle Plugin‏ (AGP) 8.2.

תבנית המודול Android Studio Baseline Profile Generator (מחולל פרופילים בסיסיים) מאפשרת ליצור באופן אוטומטי מודול חדש כדי ליצור פרופילים בסיסיים ולבצע השוואה ביניהם. הפעלת התבנית יוצרת את רוב ההגדרות האופייניות של הבנייה, את פרופיל הבסיס ואת קוד האימות. התבנית יוצרת קוד ליצירה של פרופילי בסיס ולהשוואה ביניהם, כדי למדוד את זמן ההפעלה של האפליקציה.

הגדרה של מודול פרופיל הבסיס

כדי להריץ את תבנית המודול של פרופיל הבסיס:

  1. בוחרים באפשרות קובץ > חדש > מודול חדש.
  2. בוחרים את התבנית Baseline Profile Generator בחלונית Templates ומגדירים אותה:
    איור 1. תבנית של מודול ליצירת פרופיל Baseline.

    השדות בתבנית הם:

    • אפליקציית היעד: מגדירה עבור איזו אפליקציה נוצר פרופיל הבסיס. אם יש לכם רק מודול אפליקציה אחד בפרויקט, יהיה רק פריט אחד ברשימה הזו.
    • שם המודול: השם שרוצים לתת למודול של פרופיל הבסיס שנוצר.
    • Package name: שם החבילה שרוצים עבור מודול Baseline Profile.
    • שפה: האם רוצים שהקוד שייווצר יהיה ב-Kotlin או ב-Java.
    • שפת הגדרת ה-Build: בוחרים אם רוצים להשתמש ב-Kotlin Script ‏ (KTS) או ב-Groovy בשביל סקריפטים של הגדרת ה-Build.
    • שימוש במכשיר בניהול Gradle: האם אתם משתמשים במכשירים בניהול Gradle כדי לבדוק את האפליקציה.
  3. לוחצים על סיום והמודול החדש נוצר. אם אתם משתמשים בבקרת מקור, יכול להיות שתתבקשו להוסיף את קובצי המודול החדשים שנוצרו לבקרת המקור.

הגדרת מחולל פרופיל הבסיס

המודול החדש שנוצר מכיל בדיקות גם ליצירה ולבדיקה של פרופיל הבסיס וגם לבדיקה של הפעלה בסיסית של האפליקציה בלבד. מומלץ להוסיף להם תרחישי שימוש נפוצים (CUJ) ותהליכי עבודה מתקדמים להפעלת סטארטאפים. חשוב לוודא שכל הבדיקות שקשורות להפעלת האפליקציה נמצאות בבלוק rule עם includeInStartupProfile שמוגדר ל-true. לעומת זאת, כדי להשיג ביצועים אופטימליים, חשוב לוודא שכל הבדיקות שלא קשורות להפעלת האפליקציה לא נכללות בפרופיל ההפעלה. אופטימיזציות של הפעלת אפליקציות משמשות להגדרת חלק מיוחד של פרופיל בסיסי שנקרא פרופיל הפעלה.

כדי לשמור על יכולת התחזוקה, מומלץ להפריד את תרחישי השימוש האלה מחוץ לקוד של פרופיל הבסיס ושל ההשוואה לשוק שנוצר, כדי שאפשר יהיה להשתמש בהם גם בשביל זה וגם בשביל זה. המשמעות היא שהשינויים ב-CUJ שלכם ישמשו באופן עקבי.

יצירה והתקנה של פרופיל Baseline

תבנית המודול Baseline Profile מוסיפה הגדרת הרצה חדשה כדי ליצור את Baseline Profile. אם אתם משתמשים בגרסאות מוצר, Android Studio יוצר כמה הגדרות הפעלה כדי שתוכלו ליצור פרופילי בסיס נפרדים לכל גרסה.

הגדרת ההרצה Generate Baseline Profile.
איור 2. הפעלת ההגדרה הזו יוצרת את פרופיל הבסיס.

כשמסיימים את ההפעלה של הגדרת ההרצה Generate Baseline Profile, הפרופיל הבסיסי שנוצר מועתק לקובץ src/variant/generated/baselineProfiles/baseline-prof.txt במודול שיוצרים לו פרופיל. אפשרויות הווריאנט הן סוג גרסת ה-build של הגרסה או וריאנט של גרסת ה-build שכולל את סוג גרסת ה-build של הגרסה.

פרופיל הבסיס שנוצר נוצר במקור ב-build/outputs. הנתיב המלא נקבע לפי הווריאציה או הגרסה של האפליקציה שיוצרים לה פרופיל, ולפי סוג המכשיר שמשמש ליצירת הפרופיל: מכשיר שמנוהל על ידי Gradle או מכשיר מחובר. אם משתמשים בשמות שבהם נעשה שימוש בקוד ובהגדרות הבנייה שנוצרו על ידי התבנית, פרופיל הבסיס נוצר בקובץ build/outputs/managed_device_android_test_additional_output/nonminifiedrelease/pixel6Api31/BaselineProfileGenerator_generate-baseline-prof.txt. סביר להניח שלא תצטרכו לבצע אינטראקציה ישירה עם הגרסה הזו של פרופיל הבסיס שנוצר, אלא אם אתם מעתיקים אותה באופן ידני למודולים של היעד (לא מומלץ).

יצירת פרופיל בסיסי חדש באמצעות AGP 8.1

אם אין לכם אפשרות להשתמש בתבנית של מודול פרופיל בסיסי, תוכלו להשתמש בתבנית של מודול Macrobenchmark ובתוסף Baseline Profile Gradle כדי ליצור פרופיל בסיסי חדש. מומלץ להשתמש בכלים האלה החל מ-Android Studio Giraffe ומ-AGP 8.1.

כך יוצרים פרופיל בסיסי חדש באמצעות תבנית המודול Macrobenchmark ותוסף Gradle של פרופיל בסיסי:

  1. מגדירים מודול Macrobenchmark בפרויקט Gradle.
  2. מגדירים מחלקה חדשה בשם BaselineProfileGenerator:
    class BaselineProfileGenerator {
        @get:Rule
        val baselineProfileRule = BaselineProfileRule()
    
        @Test
        fun startup() = baselineProfileRule.collect(
            packageName = "com.example.app",
            profileBlock = {
                startActivityAndWait()
            }
        )
    }

    הגנרטור יכול לכלול אינטראקציות עם האפליקציה מעבר להפעלה שלה. כך אפשר לבצע אופטימיזציה של ביצועי זמן הריצה של האפליקציה, למשל גלילה ברשימות, הפעלת אנימציות וניווט בתוך Activity. דוגמאות נוספות לבדיקות שמשתמשות ב-@BaselineProfileRule כדי לשפר תהליכים קריטיים שעוברים המשתמשים.

  3. מוסיפים את הפלאגין Baseline Profile Gradle‏ (libs.plugins.androidx.baselineprofile). הפלאגין מקל על יצירת פרופילים של בסיס ועל התחזוקה שלהם בעתיד.

  4. כדי ליצור את פרופיל הבסיס, מריצים את משימות Gradle‏ :app:generateBaselineProfile או :app:generateVariantBaselineProfile בטרמינל.

    מריצים את הגנרטור כבדיקה עם מכשור במכשיר פיזי עם הרשאות בסיס, באמולטור או במכשיר בניהול Gradle. אם אתם משתמשים במכשיר מנוהל של Gradle, צריך להגדיר את aosp כ-systemImageSource, כי נדרשת גישת root כדי להשתמש בכלי ליצירת פרופיל בסיסי.

    בסיום משימת היצירה, פרופיל הבסיס מועתק אל app/src/variant/generated/baselineProfiles.

יצירת פרופיל בסיסי חדש ללא תבניות

מומלץ ליצור פרופיל Baseline באמצעות תבנית מודול פרופיל Baseline (המועדפת) או תבנית Macrobenchmark ב-Android Studio, אבל אפשר גם להשתמש בפלאגין Baseline Profile Gradle לבד. מידע נוסף על הפלאגין Baseline Profile Gradle זמין במאמר בנושא הגדרת יצירה של פרופיל בסיסי.

כך יוצרים פרופיל Baseline באמצעות פלאגין Baseline Profile Gradle ישירות:

  1. יוצרים מודול חדש של com.android.test – לדוגמה, :baseline-profile.
  2. מגדירים את הקובץ build.gradle.kts עבור :baseline-profile:

    1. מחילים את הפלאגין androidx.baselineprofile.
    2. מוודאים שהתג targetProjectPath מפנה למודול :app.
    3. אפשר גם להוסיף מכשיר בניהול Gradle (GMD). בדוגמה הבאה, זה pixel6Api31. אם לא מציינים, הפלאגין משתמש במכשיר מחובר, אמולטור או מכשיר פיזי.
    4. מחילים את ההגדרה הרצויה, כמו בדוגמה הבאה.

    Kotlin

    plugins {
        id("com.android.test")
        id("androidx.baselineprofile")
    }
    
    android {
        defaultConfig {
            ...
        }
    
        // Point to the app module, the module that you're generating the Baseline Profile for.
        targetProjectPath = ":app"
        // Configure a GMD (optional).
        testOptions.managedDevices.devices {
            pixel6Api31(com.android.build.api.dsl.ManagedVirtualDevice) {
                device = "Pixel 6"
                apiLevel = 31
                systemImageSource = "aosp"
            }
        }
    }
    
    dependencies { ... }
    
    // Baseline Profile Gradle plugin configuration. Everything is optional. This
    // example uses the GMD added earlier and disables connected devices.
    baselineProfile {
        // Specifies the GMDs to run the tests on. The default is none.
        managedDevices += "pixel6Api31"
        // Enables using connected devices to generate profiles. The default is
        // `true`. When using connected devices, they must be rooted or API 33 and
        // higher.
        useConnectedDevices = false
    }

    גרוב

    plugins {
        id 'com.android.test'
        id 'androidx.baselineprofile'
    }
    
    android {
        defaultConfig {
            ...
        }
    
        // Point to the app module, the module that you're generating the Baseline Profile for.
        targetProjectPath ':app'
        // Configure a GMD (optional).
        testOptions.managedDevices.devices {
            pixel6Api31(com.android.build.api.dsl.ManagedVirtualDevice) {
                device 'Pixel 6'
                apiLevel 31
                systemImageSource 'aosp'
            }
        }
    }
    
    dependencies { ... }
    
    // Baseline Profile Gradle plugin configuration. Everything is optional. This
    // example uses the GMD added earlier and disables connected devices.
    baselineProfile {
        // Specifies the GMDs to run the tests on. The default is none.
        managedDevices ['pixel6Api31']
        // Enables using connected devices to generate profiles. The default is
        // `true`. When using connected devices, they must be rooted or API 33 and
        // higher.
        useConnectedDevices false
    }
  3. יוצרים בדיקה של פרופיל בסיסי במודול הבדיקה :baseline-profile. בדוגמה הבאה מוצגת בדיקה שמתחילה את האפליקציה ומחכה למצב סרק.

    Kotlin

    class BaselineProfileGenerator {
    
        @get:Rule
        val baselineRule = BaselineProfileRule()
    
        @Test
        fun startupBaselineProfile() {
            baselineRule.collect("com.myapp") {
                startActivityAndWait()
            }
        }
    }

    Java

    public class BaselineProfileGenerator {
    
        @Rule
        Public BaselineProfileRule baselineRule = new BaselineProfileRule();
    
        @Test
        Public void startupBaselineProfile() {
            baselineRule.collect(
                "com.myapp",
                (scope -> {
                    scope.startActivityAndWait();
                    Return Unit.INSTANCE;
                })
            )
        }
    }
  4. מעדכנים את הקובץ build.gradle.kts במודול האפליקציה, לדוגמה :app.

    1. מחילים את הפלאגין androidx.baselineprofile.
    2. מוסיפים תלות baselineProfile למודול :baseline-profile.

    Kotlin

    plugins {
        id("com.android.application")
        id("androidx.baselineprofile")
    }
    
    android {
        // There are no changes to the `android` block.
        ...
    }
    
    dependencies {
        ...
        // Add a `baselineProfile` dependency on the `:baseline-profile` module.
        baselineProfile(project(":baseline-profile"))
    }

    גרוב

    plugins {
        id 'com.android.application'
        id 'androidx.baselineprofile'
    }
    
    android {
        // No changes to the `android` block.
        ...
    }
    
    dependencies {
        ...
        // Add a `baselineProfile` dependency on the `:baseline-profile` module.
        baselineProfile ':baseline-profile'
    }
  5. מריצים את משימות Gradle‏ :app:generateBaselineProfile או :app:generateVariantBaselineProfile כדי ליצור את הפרופיל.

  6. בסיום משימת היצירה, פרופיל הבסיס מועתק אל app/src/variant/generated/baselineProfiles.

יצירת פרופיל בסיסי חדש באמצעות AGP 7.3-7.4

אפשר ליצור פרופילים בסיסיים באמצעות AGP 7.3-7.4, אבל מומלץ מאוד לשדרג לפחות ל-AGP 8.1 כדי שתוכלו להשתמש בתוסף Gradle של הפרופיל הבסיסי ובתכונות העדכניות שלו.

אם אתם צריכים ליצור פרופילים של ביצועים בסיסיים באמצעות AGP מגרסאות 7.3 עד 7.4, השלבים זהים לשלבים של AGP מגרסה 8.1, עם ההבדלים הבאים:

החלה ידנית של כללים שנוצרו

מחולל פרופיל הבסיס יוצר קובץ טקסט בפורמט קריא (HRF) במכשיר ומעתיק אותו למחשב המארח. כדי להחיל את הפרופיל שנוצר על הקוד, פועלים לפי השלבים הבאים:

  1. מאתרים את קובץ ה-HRF בתיקיית ה-build של המודול שבו יצרתם את הפרופיל: [module]/build/outputs/managed_device_android_test_additional_output/[device].

    הפרופילים נקראים לפי [class name]-[test method name]-baseline-prof.txt התבנית הבאה: BaselineProfileGenerator-startup-baseline-prof.txt.

  2. מעתיקים את הפרופיל שנוצר אל src/main/ ומשנים את שם הקובץ ל-baseline-prof.txt.

  3. כדי להפעיל קומפילציה מקומית של פרופיל בסיסי במקרים שבהם פרופילים ב-Cloud לא זמינים, צריך להוסיף תלות בספריית ProfileInstaller בקובץ build.gradle.kts של האפליקציה. זו הדרך היחידה להעביר פרופיל Baseline באופן מקומי.

    dependencies {
         implementation("androidx.profileinstaller:profileinstaller:1.4.1")
    }
    
  4. מבצעים build של גרסת הייצור של האפליקציה בזמן שהכללים של HRF מורכבים לפורמט בינארי ונכללים ב-APK או ב-AAB. לאחר מכן, מפיצים את האפליקציה כרגיל.

השוואה לפרופיל Baseline

כדי להשוות את פרופיל הבסיס, יוצרים הגדרה חדשה של הרצת בדיקה עם מכשור ב-Android מפעולת השוליים שמבצעת את ההשוואות שהוגדרו בקובץ StartupBenchmarks.kt או StartupBencharks.java. מידע נוסף על בדיקות השוואה לשוק זמין במאמרים יצירת מחלקה של בדיקת השוואה לשוק ואוטומציה של מדידה באמצעות ספריית בדיקת ההשוואה לשוק.

איור 3. הרצת בדיקות Android באמצעות הפעולה
Run Android Tests from the gutter.

כשמריצים את הפקודה הזו ב-Android Studio, פלט הבנייה מכיל פרטים על שיפורי המהירות שפרופיל הבסיס מספק:

StartupBenchmarks_startupCompilationBaselineProfiles
timeToInitialDisplayMs   min 161.8,   median 178.9,   max 194.6
StartupBenchmarks_startupCompilationNone
timeToInitialDisplayMs   min 184.7,   median 196.9,   max 202.9

תיעוד של כל נתיבי הקוד הנדרשים

שני מדדי המפתח למדידת זמני ההפעלה של האפליקציה הם:

הזמן להצגה ראשונית (TTID)
הזמן שנדרש להצגת הפריים הראשון של ממשק המשתמש של האפליקציה.
הזמן עד להצגה מלאה (TTFD)
הזמן עד להצגת התוכן שנטען באופן אסינכרוני אחרי שהפריים הראשוני מוצג.

המדד TTFD מדווח אחרי שקוראים לשיטה reportFullyDrawn() של האובייקט ComponentActivity. אם אף פעם לא מתבצעת קריאה ל-reportFullyDrawn(), במקום זאת מדווח על TTID. יכול להיות שתצטרכו לדחות את הקריאה ל-reportFullyDrawn() עד אחרי שהטעינה האסינכרונית תסתיים. לדוגמה, אם ממשק המשתמש מכיל רשימה דינמית כמו RecyclerView או lazy list, יכול להיות שהרשימה תאוכלס על ידי משימת רקע שתושלם אחרי שהרשימה תוצג בפעם הראשונה, ולכן אחרי שממשק המשתמש יסומן כרשימה שמוצגת במלואה. במקרים כאלה, קוד שמופעל אחרי שהממשק מגיע למצב של ציור מלא לא נכלל בפרופיל הבסיסי.

כדי לכלול את אכלוס הרשימה כחלק מפרופיל הבסיס, צריך לקבל את FullyDrawnReporter באמצעות getFullyDrawnReporter() ולהוסיף לו כלי דיווח בקוד האפליקציה. משחררים את הדיווח אחרי שמשימת הרקע מסיימת לאכלס את הרשימה. הפונקציה FullyDrawnReporter לא קוראת לשיטה reportFullyDrawn() עד שכל ה-reporters משוחררים. כך, פרופיל הבסיס כולל את נתיבי הקוד שנדרשים כדי לאכלס את הרשימה. השינוי הזה לא משפיע על התנהגות האפליקציה מבחינת המשתמש, אבל הוא מאפשר ל-Baseline Profile לכלול את כל נתיבי הקוד הנדרשים.

אם האפליקציה שלכם משתמשת ב-Jetpack Compose, אתם יכולים להשתמש בממשקי ה-API הבאים כדי לציין את מצב הציור המלא:

  • ReportDrawn מציין שהרכיב המורכב מוכן מיידית לאינטראקציה.
  • ReportDrawnWhen מקבל פונקציית חיזוי, כמו list.count > 0, כדי לציין מתי הרכיב הניתן להרכבה מוכן לאינטראקציה.
  • ReportDrawnAfter מקבלת שיטת השהיה, וכשהיא מסתיימת, היא מציינת שהרכיב הניתן להרכבה מוכן לאינטראקציה.