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

יצירת פרופילים באופן אוטומטי לכל גרסת אפליקציה באמצעות ספריית 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 של הפרופיל הבסיסי ובתכונות העדכניות שלו.

אם אתם צריכים ליצור פרופילים של Baseline עם 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. יוצרים את גרסת הייצור של האפליקציה בזמן שכללי ה-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 או רשימה עצלה, יכול להיות שהרשימה תאוכלס על ידי משימת רקע שתושלם אחרי שהרשימה תוצג בפעם הראשונה, ולכן אחרי שממשק המשתמש יסומן כרשימה שמוצגת במלואה. במקרים כאלה, קוד שמופעל אחרי שהממשק מגיע למצב של ציור מלא לא נכלל בפרופיל הבסיסי.

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

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

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