סקירה כללית של פרופילים בסיסיים

פרופילים של Baseline משפרים את מהירות הרצת הקוד ב-30% בערך מההפעלה הראשונה, כי הם מאפשרים להימנע משלבי פרשנות וקימפול just-in-time (JIT) לנתיבי הקוד הכלולים.

כשמצרפים פרופיל Baseline לאפליקציה או לספרייה, סביבת זמן הריצה ל-Android‏ (ART) יכולה לבצע אופטימיזציה של נתיבי קוד ספציפיים באמצעות קימפול מראש (AOT), וכך לשפר את הביצועים לכל משתמש חדש ולכל עדכון של האפליקציה. זו אופטימיזציה מונחית פרופיל (PGO) שמאפשרת לאפליקציות להעלות את איכות ההפעלה, לצמצם בעיות בממשק (jank) שקשורות לאינטראקציה, ולשפר את הביצועים הכוללים של זמן הריצה למשתמשים כבר מההפעלה הראשונה.

השיפורים האלה בביצועים מובילים ישירות לשיפור המדדים העסקיים, כמו שימור משתמשים, עסקאות ודירוגים. אפשר לקרוא עוד על ההשפעה של הביצועים על מדדים עסקיים בסיפורים של Josh,‏ Lyft,‏ TikTok ו-Zomato.

היתרונות של פרופילים של Baseline

פרופילים של Baseline משפרים את כל האינטראקציות של המשתמשים – כמו הפעלת האפליקציה, מעבר בין מסכים או גלילה בתוכן – כבר מהפעם הראשונה שהם מפעילים את האפליקציה. הם יכולים להגביר את המהירות ויכולת התגובה של האפליקציה, וכך להוביל ליותר משתמשים פעילים ביום (DAU) ולשיעור גבוה יותר של משתמשים שחוזרים לאפליקציה.

פרופילים של Baseline עוזרים לבצע אופטימיזציה מעבר להפעלה של האפליקציה. הם מאפשרים למשתמשים לבצע פעולות נפוצות שמשפרות את זמן הריצה של האפליקציה החל מההפעלה הראשונה. הקימפול המודרך מסוג AOT לא מסתמך על המכשירים של המשתמשים. אפשר לבצע את השלב הזה פעם אחת לכל גרסה במחשב פיתוח במקום במכשיר נייד. כשמשתמשים בפרופיל Baseline כדי לשלוח גרסאות, האופטימיזציות של האפליקציה זמינות הרבה יותר מהר מאשר כשמסתמכים רק על פרופילים של Cloud.

כשלא משתמשים בפרופיל Baseline, כל קוד האפליקציה עובר קימפול JIT בזיכרון אחרי שהוא מפוענח, או שהוא נכתב לקובץ odex ברקע כשהמכשיר לא פעיל. אחרי התקנה או עדכון של אפליקציה, חוויית השימוש לא תהיה אופטימלית בהפעלה הראשונה, אלא רק אחרי שיימצאו נתיבי קוד חדשים שיעברו אופטימיזציה. אפליקציות רבות מדווחות על שיפור של כ-30% בביצועים אחרי האופטימיזציה.

פרופילים להפעלה

פרופילים להפעלה דומים לפרופילים של Baseline, אבל ההבדל הוא שנעשה בהם שימוש בזמן הקימפול ולא לאופטימיזציה במכשיר. פרופיל של הפעלה משמש לאופטימיזציה של הפריסה של קובץ ה-DEX כדי לשפר את זמני ההפעלה. הקוד שזוהה בפרופיל ההפעלה מוכנס לקובץ classes.dex הראשי וקוד אחר מוכנס לקובצי DEX נפרדים. הפעולה הזו משפרת את זמני ההפעלה על ידי צמצום מספר השגיאות בדפים במהלך הפעלת האפליקציה. למידע נוסף על האופן שבו פרופילים להפעלה ואופטימיזציות של פריסת DEX יכולים לשפר את זמני ההפעלה של האפליקציה, אפשר לעיין במאמר שכאן.

איך להתחיל

כדי להתחיל לשפר את הביצועים באפליקציה הקיימת, אפשר לעיין במאמר בנושא יצירת פרופילים של Baseline.

יצירת פרופיל לעומת גרסאות build להפצה

חשוב להבין את ההבדל בין הגדרות ה-build שנדרשות כשיוצרים קבצים של פרופילים של Baseline ושל הפעלה (לדוגמה, baseline-prof.txt ו-startup-prof.txt) לבין הגדרות ה-build שנדרשות כשיוצרים את קובץ ה-APK הסופי של הגרסה שמופצת, שמשתמש בפרופילים האלה.

כשיוצרים קובצי פרופיל (לדוגמה, benchmark):

כדי לוודא שכללי הפרופיל שנוצרו תואמים במדויק לחתימות השיטה בקוד, צריך להשבית את ההסתרה והאופטימיזציה (R8) של וריאציית ה-build שמשמשת ליצירת הפרופיל. הווריאנט הזה חייב להיות שונה מהווריאנט של גרסת ה-release, שבו מופעלים ערפול קוד ואופטימיזציה. כדי לעשות את זה, מגדירים את isMinifyEnabled = false כמשתנה build של יצירת הפרופיל. אם אתם לא משתמשים בפלאגין Baseline Profile Gradle, אתם צריכים לוודא שהפלאגינים -dontobfuscate ו--dontoptimize מופעלים. ‫Baseline Profile Gradle Plugin מטפל בהגדרה הזו באופן אוטומטי.

כשיוצרים את ה-APK של הגרסה הסופית:

כדי ליהנות מהסתרת קוד, מהקטנה ומאופטימיזציה, ב-build של הגרסה צריך להיות תמיד isMinifyEnabled = true. ‫R8 משכתב באופן אוטומטי את הכללים מקובצי הפרופיל הלא-מטושטשים כדי להתאים לקוד המטושטש והממוטב ב-APK של הגרסה. כדי שאופטימיזציה של פריסת DEX (שמבוססת על פרופילים להפעלה) תהיה יעילה, האפליקציה שאתם מפרסמים צריכה להיות מעורפלת ולהשתמש ב-R8 עם כל האופטימיזציות מופעלות.

שרשרת התלות מספקת גרסאות יציבות וגרסאות פיתוח. כדי ליצור ולהתקין פרופיל Baseline, צריך להשתמש בגרסאות הנתמכות הבאות או בגרסאות מתקדמות יותר של הפלאגין של Android Gradle, ספריית Macrobenchmark והכלי להתקנת פרופילים. התלויות האלה נדרשות בזמנים שונים, והן פועלות יחד בתור toolchain כדי לאפשר פרופיל Baseline אופטימלי.

  • ‫Android Gradle plugin: ‏ com.android.tools.build:8.0.0
  • ספריית Macrobenchmark: androidx.benchmark:benchmark-macro-junit4:1.4.1
  • הכלי להתקנת פרופילים: androidx.profileinstaller:profileinstaller:1.4.1

מומלץ להשתמש בגרסה העדכנית של AGP כדי ליצור ולנהל פרופילים של Baseline. אלה הפונקציות העיקריות שזמינות בגרסאות שונות של AGP:

גרסת AGP תכונות
8.4 התקנות מקומיות של גרסאות build שלא ניתן לנפות בהן באגים באמצעות כלי שורת הפקודה של Gradle wrapper או Android Studio מתקינות פרופילים של Baseline. כך הביצועים של גרסת ה-build המקומית שלכם תואמים יותר לביצועים בסביבת הייצור. העדכון הזה לא משפיע על ביצועי הייצור של הפרופילים של Baseline.
8.3
  • תמיכה מלאה בספרייה של קבוצת מקורות (מודולים של ספריות): אפשר להצהיר על כמה קובצי מקור של פרופיל Baseline ולהשתמש בספריות שמותאמות לווריאנטים, כמו src/free/generated/baselineProfiles/baseline-prof1.txt, במודולים של ספריות ושל אפליקציות.
  • פרופילים של Baseline כוללים מחלקות שהוסר מהן סוכר תחבירי.
8.2
  • שכתוב כללים ב-R8:‏ D8 ו-R8 יכולים להמיר כללים קריאים לאנשים בפרופיל ההפעלה ובפרופיל Baseline, כדי לתעד באופן מלא את כל הכללים שנדרשים לכם כדי לשפר את ביצועי האפליקציה. כך תוכלו ליצור פרופילים מ-build לא מכווץ ולהחיל אותם על build מכווץ של גרסת הפצה. השיפורים האלה מגדילים את הכיסוי של שיטות בפרופיל Baseline בכ-30% ומשפרים את ביצועי האפליקציה בכ-15%.
  • פרופילים של הפעלה: יוצרים את הסוג החדש הזה של פרופיל Baseline כדי לספק מידע על הפריסה של הקוד ב-DEX. זה משפר את ביצועי ההפעלה בעוד כ-15% או הרבה יותר באפליקציות גדולות.
‫8.0 הגרסה המומלצת המינימלית: אפשר להשתמש בפלאגין Baseline Profile Gradle כדי ליצור פרופילים של Baseline באמצעות משימת Gradle אחת.
  • תמיכה מלאה בספריית קבצים של מקורות (מודולים של אפליקציות): אפשר להצהיר על כמה קובצי מקור של פרופיל Baseline ולהשתמש בספריות שמותאמות לווריאנטים, כמו src/free/generated/baselineProfiles/baseline-prof1.txt.
7.4 הגרסה המינימלית הנתמכת: אפליקציות יכולות להשתמש בפרופילים של Baseline מספריות ולספק פרופיל Baseline משלהן בקובץ src/main/baseline-prof.txt.
  • פרופילים של Baseline נארזים בצורה נכונה כשיוצרים את ה-APK מ-App Bundle (בעיה מספר 230361284).
  • באפליקציות עם יותר מקובץ .dex אחד, הפרופילים של Baseline נארזים בצורה נכונה עבור קובץ .dex הראשי.
  • תמיכה ב-D8 וב-R8 ביצירת פרופילים להפעלה מתוך build שבו הערך של isMinifyEnabled מוגדר כ-false.

דוגמה ליצירת פרופיל

הדוגמה הבאה מציגה מחלקה ליצירת פרופיל Baseline להפעלת אפליקציה, וכן כמה אירועים של ניווט וגלילה באמצעות ספריית Macrobenchmark המומלצת:

@OptIn(ExperimentalBaselineProfilesApi::class)
class BaselineProfileGenerator {
    @get:Rule
    val baselineProfileRule = BaselineProfileRule()

    @Test
    fun appStartupAndUserJourneys() {
        baselineProfileRule.collect(packageName = PACKAGE_NAME) {
            // App startup journey.
            startActivityAndWait()

            device.findObject(By.text("COMPOSE LAZYLIST")).clickAndWait(Until.newWindow(), 1_000)
            device.findObject(By.res("myLazyColumn")).also {
                it.fling(Direction.DOWN)
                it.fling(Direction.UP)
            }
            device.pressBack()
        }
    }
}

אפשר לראות את הקוד הזה בהקשר מלא ובפירוט רב יותר כחלק מדוגמאות הביצועים שלנו ב-GitHub.

הפרטים שצריך לכלול

כשמשתמשים בפרופילים של Baseline באפליקציה, אפשר לכלול קוד הפעלה של האפליקציה ואינטראקציות נפוצות של משתמשים, כמו ניווט בין מסכים או גלילה. אפשר גם לאסוף נתונים של תהליכים שלמים, כמו הרשמה, התחברות או תשלום. פרופילים של Baseline יכולים לעזור לכם לשפר את ביצועי זמן הריצה של כל תהליך משתמש שחשוב לכם.

אם אתם עורכים ניסוי עם גישות שונות לשיפור הביצועים, כדאי לכלול פרופילים של Baseline בשתי קבוצות הניסוי. כך תוכלו להבין את התוצאות בקלות רבה יותר, כי תדעו שכל המשתמשים מריצים קוד מקומפל.

ספריות יכולות לספק פרופילים משלהן של Baseline ולשלוח אותם עם גרסאות כדי לשפר את ביצועי האפליקציה. לדוגמה, אפשר לעיין בקטע שימוש בפרופיל Baseline במאמר בנושא ביצועים של Jetpack פיתוח נייטיב.

איך פועלים פרופילים של Baseline

במהלך פיתוח האפליקציה או הספרייה, כדאי להגדיר פרופילים של Baseline כדי לכסות אינטראקציות נפוצות של משתמשים שבהן זמן הרינדור או זמן האחזור חשובים. כך הם פועלים:

  1. כללי פרופיל שקריאים לאנשים נוצרים עבור האפליקציה ומקומפלים לפורמט בינארי. אפשר למצוא אותם ב-assets/dexopt/baseline.prof. לאחר מכן אפשר להעלות את קובץ ה-AAB ל-Google Play כרגיל.

  2. מערכת Google Play מעבדת את הפרופיל ושולחת אותו ישירות למשתמשים יחד עם קובץ ה-APK. במהלך ההתקנה, ART מבצע קימפול AOT של השיטות בפרופיל, וכתוצאה מכך השיטות האלה רצות מהר יותר. אם הפרופיל מכיל שיטות שמשמשות להפעלת האפליקציה או במהלך רינדור של פריים, יכול להיות שזמני ההפעלה יהיו מהירים יותר עם פחות בעיות בממשק (jank).

  3. התהליך הזה פועל לצד צבירת פרופילים של Cloud כדי לשפר את הביצועים על סמך השימוש בפועל באפליקציה לאורך זמן.

תרשים 1. בתרשים הזה מוצג תהליך העבודה של פרופיל Baseline, מההעלאה ועד למסירה למשתמש הקצה, ואיך תהליך העבודה הזה קשור לפרופילים ב-Cloud.

פרופילים של Cloud

יחד עם פרופילים של Baseline, פרופילים של Cloud מציעים סוג נוסף של PGO – שנצבר על ידי Google Play Store ומופץ לקימפול בזמן ההתקנה.

פרופילים של Cloud מבוססים על אינטראקציות של משתמשים עם האפליקציה בעולם האמיתי. עם זאת, לוקח כמה שעות או ימים אחרי עדכון עד שהם מופצים, ולכן הזמינות שלהם מוגבלת. עד שהפרופילים יופצו באופן מלא, הביצועים לא יהיו אופטימליים באפליקציות חדשות או שעברו עדכון. בנוסף, פרופילים של Cloud תומכים רק במכשירי Android עם Android 9 (רמת API‏ 28) ומעלה, והם מתאימים רק לאפליקציות עם בסיס משתמשים גדול מספיק.

התנהגות הקימפול בגרסאות שונות של Android

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

גרסת Android שיטת הקימפול גישת האופטימיזציה
‫5 עד 6 (רמת API‏ 21 עד 23) ‫AOT מלא האופטימיזציה של האפליקציה מתבצעת במהלך ההתקנה, ולכן זמני ההמתנה לשימוש באפליקציה ארוכים יותר, השימוש בזיכרון ה-RAM ובכונן גדל וזמני הטעינה של הקוד מהדיסק ארוכים יותר. כל אלה עלולים להגדיל את זמני ההפעלה מההתחלה (cold startup).
‫7 עד 8.1 (API ברמה 24 עד 27) ‫AOT חלקי (פרופיל Baseline) פרופילים של Baseline מותקנים על ידי androidx.profileinstaller בהפעלה הראשונה, כשהמודול של האפליקציה מגדיר את התלות הזו. ‫ART יכול לשפר את זה עוד יותר על ידי הוספה של כללי פרופיל במהלך השימוש באפליקציה, וקימפול שלהם כשהמכשיר לא פעיל. כך מתבצעת אופטימיזציה של המקום בכונן ושל הזמן שנדרש לטעינת הקוד מהדיסק, וזמן ההמתנה לאפליקציה מתקצר.
‫9 (רמת API‏ 28) ומעלה ‫AOT חלקי (פרופיל Baseline + פרופיל Cloud) ‫Play משתמש בפרופילים של Baseline במהלך התקנות של אפליקציות כדי לבצע אופטימיזציה של חבילות ה-APK ושל פרופילים של Cloud – אם הם זמינים. אחרי ההתקנה, פרופילים של ART מועלים ל-Play, נצברים ומסופקים כפרופילים של Cloud למשתמשים אחרים כשהם מתקינים או מעדכנים את האפליקציה.

בעיות מוכרות

הנה בעיות שיכולות לקרות והפתרונות שלהן, או בעיות שעדיין מתפתחות דרכים לעקוף אותן:

  • יכול להיות שייכשל ניסיון ליצור פרופיל Baseline בגלל הגדרות ההרשאות במכשירים מסוימים, כולל מכשירי OnePlus. כדי לעקוף את הבעיה, משביתים את האפשרות השבתת מעקב אחר הרשאות בהגדרות של אפשרויות למפתחים.

  • יצירת פרופיל Baseline לא נתמכת במכשירים של Firebase Test Lab, כולל מכשירי Test Lab שמנוהלים על ידי Gradle (בעיה מספר 285187547).

  • כדי לספק פרופילים של Baseline לספריות בהצלחה, צריך להשתמש בתוסף Baseline Profile Gradle בגרסה 1.2.3 או ב-AGP בגרסה 8.3, לכל הפחות (בעיה מספר 313992099).

  • אם יוצרים פרופילים של Baseline באמצעות הפקודה ./gradlew app:generateBaselineProfile, גם נקודות ההשוואה במודול הבדיקה רצות והתוצאות נמחקות. במקרה כזה, אפשר ליצור רק את הפרופילים של Baseline על ידי הפעלת הפקודה עם -P android.testInstrumentationRunnerArguments.androidx.benchmark.enabledRules=BaselineProfile. הבעיה הזו תוקנה ב-AGP 8.2.

  • הפקודה ליצירת פרופילים של Baseline לכל סוגי ה-build‏ – ./gradlew app:generateBaselineProfile – יוצרת פרופילים של Baseline רק לגרסת build להפצה. הבעיה הזו תוקנה ב-AGP 8.1.

  • יכול להיות שערוצי הפצה של אפליקציות שלא נמצאים בחנות Google Play לא יתמכו בשימוש בפרופילים של Baseline בזמן ההתקנה. משתמשים באפליקציות שהותקנו דרך הערוצים האלה לא רואים את היתרונות עד שהתהליך dexopt פועל ברקע – בדרך כלל זה קורה במהלך הלילה.

  • שיתוף פנימי של אפליקציות בחנות Play לא תומך בפרופילים של Baseline, אבל מסלול הבדיקה הפנימית כן תומך.

  • אופטימיזציות של הסוללה במכשירים מסוימים, כמו מכשירי Huawei, עלולות להפריע להתקנת הפרופיל. כדי לוודא שהפרופילים מותקנים בצורה יעילה, צריך להשבית את כל האופטימיזציות של הסוללה במכשירי ההשוואה.

מקורות מידע נוספים