הפעלת אופטימיזציית האפליקציה

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

  • זמן הפעלה מהיר יותר
  • שיפורים בביצועי העיבוד והזמן הריצה
  • פחות מקרי ANR

כדי להפעיל אופטימיזציה של האפליקציה, צריך להגדיר את isMinifyEnabled = true (לאופטימיזציה של הקוד) ואת isShrinkResources = true (לאופטימיזציה של המשאבים) בסקריפט הבנייה ברמת האפליקציה של גרסת ההפצה, כמו שמוצג בקוד הבא. מומלץ להפעיל תמיד את שתי ההגדרות. מומלץ גם להפעיל אופטימיזציה של האפליקציה רק בגרסה הסופית של האפליקציה שאתם בודקים לפני הפרסום – בדרך כלל גרסת ה-release – כי האופטימיזציות מאריכות את זמן הבנייה של הפרויקט ויכולות להקשות על ניפוי הבאגים בגלל האופן שבו הן משנות את הקוד.

Kotlin

android {
    buildTypes {
        release {

            // Enables code-related app optimization.
            isMinifyEnabled = true

            // Enables resource shrinking.
            isShrinkResources = true

            proguardFiles(
                // Default file with automatically generated optimization rules.
                getDefaultProguardFile("proguard-android-optimize.txt"),

                ...
            )
            ...
        }
    }
    ...
}

Groovy

android {
    buildTypes {
        release {

            // Enables code-related app optimization.
            minifyEnabled true

            // Enables resource shrinking.
            shrinkResources true

            // Default file with automatically generated optimization rules.
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt')

            ...
        }
    }
}

אופטימיזציה של כיווץ משאבים לאפליקציות קטנות עוד יותר

בגרסה 8.12.0 של Android Gradle Plugin ‏ (AGP) הוספנו אופטימיזציה לצמצום משאבים, שמטרתה לשלב אופטימיזציה של משאבים וקוד כדי ליצור אפליקציות קטנות ומהירות עוד יותר.

הפעלה של אופטימיזציה של צמצום המשאבים

כדי להפעיל את צינור העיבוד החדש והמשופר לצמצום משאבים בגרסה של AGP לפני 9.0.0, מוסיפים את הקוד הבא לקובץ gradle.properties של הפרויקט:

android.r8.optimizedResourceShrinking=true

אם אתם משתמשים ב-AGP 9.0.0 או בגרסה חדשה יותר, אתם לא צריכים להגדיר את android.r8.optimizedResourceShrinking=true. התכונה 'הקטנת משאבים אופטימלית' מופעלת באופן אוטומטי כשמפעילים את isShrinkResources = true בהגדרות של הקומפילציה.

אימות והגדרה של הגדרות האופטימיזציה של R8

כדי לאפשר ל-R8 להשתמש ביכולות האופטימיזציה המלאות שלו, צריך להסיר את השורה הבאה מקובץ gradle.properties של הפרויקט, אם היא קיימת:

android.enableR8.fullMode=false # Remove this line from your codebase.

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

אם R8 מופעל, כדאי גם ליצור פרופילים להפעלה כדי לשפר עוד יותר את ביצועי ההפעלה.

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

אם אתם רוצים לשפר את מהירות ה-build, במאמר הגדרת האופן שבו R8 פועל מוסבר איך להגדיר את R8 בהתאם לסביבה שלכם.

שינויים בהתנהגות של גרסאות AGP ו-R8

בטבלה הבאה מפורטות התכונות העיקריות שהוצגו בגרסאות שונות של Android Gradle Plugin‏ (AGP) ושל R8 compiler.

גרסת AGP תכונות חדשות
9.0 הקטנת משאבים שעברה אופטימיזציה: מופעלת כברירת מחדל (נשלטת באמצעות android.r8.optimizedResourceShrinking). הקטנת משאבים שעברה אופטימיזציה עוזרת לשלב הקטנת משאבים עם צינור האופטימיזציה של הקוד, וכך ליצור אפליקציות קטנות ומהירות יותר. האופטימיזציה מתבצעת גם בקוד וגם בהפניות למשאבים בו-זמנית, כך שהיא מזהה ומסירה משאבים שההפניה אליהם היא רק מקוד שלא נמצא בשימוש. זהו שיפור משמעותי לעומת תהליכי האופטימיזציה הנפרדים הקודמים.

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

סינון כללים של ספריות: התמיכה באפשרויות גלובליות (לדוגמה, -dontobfuscate) בכללים של ספריות לצרכנים הוסרה, והאפליקציות יסננו אותן. מידע נוסף זמין במאמר הוספת אפשרויות גלובליות.

בדיקות של ערכי null ב-Kotlin: מבוצע אופטימיזציה כברירת מחדל (נשלט באמצעות -processkotlinnullchecks). בגרסה הזו בוצעו גם שיפורים משמעותיים במהירות ה-build. מידע נוסף זמין במאמר בנושא אפשרויות גלובליות לאופטימיזציה נוספת.

אופטימיזציה של חבילות ספציפיות: אפשר להשתמש ב-packageScope כדי לבצע אופטימיזציה של חבילות ספציפיות. התמיכה הזו ניסיונית. מידע נוסף זמין במאמר בנושא אופטימיזציה של חבילות ספציפיות באמצעות packageScope.

אופטימיזציה כברירת מחדל: הפסקנו לתמוך ב-getDefaultProguardFile("proguard-android.txt") כי הוא כולל את -dontoptimize, ומומלץ להימנע ממנו. במקום זאת, צריך להשתמש ב-"proguard-android-optimize.txt". אם אתם צריכים להשבית את האופטימיזציה באפליקציה באופן גלובלי, צריך להוסיף את הדגל באופן ידני לקובץ Proguard.
8.12 הקטנת משאבים: נוספה תמיכה ראשונית (ההגדרה מושבתת כברירת מחדל. הפעלת האפשרות isShrinkResources). כיווץ משאבים פועל בשילוב עם R8 כדי לזהות ולהסיר משאבים לא בשימוש בצורה יעילה.

Logcat retracing: Support for automatic retracing in the Android Studio Logcat window.
8.6 שיפורים באיתור מקורות: כולל איתור מקורות לפי שם הקובץ ומספר השורה כברירת מחדל לכל הרמות של minSdk (בעבר נדרשה רמה של minSdk 26 ומעלה בגרסה 8.2).

עדכון R8 עוזר לוודא שניתן לקרוא בקלות ובבירור את עקבות המחסנית (stack traces) מגרסאות obfuscated. בגרסה הזו שופר המיפוי של מספרי השורות וקבצי המקור, כך שקל יותר לכלים כמו Logcat ב-Android Studio לשחזר באופן אוטומטי קריסות לקוד המקור המקורי.
‫8.0 מצב מלא כברירת מחדל: מצב מלא של R8 מספק אופטימיזציה חזקה הרבה יותר. ההגדרה הזו מופעלת כברירת מחדל. אפשר לבטל את ההצטרפות באמצעות android.enableR8.fullMode=false.
7.0 מצב מלא זמין: השקנו את המצב הזה כתכונה אופציונלית באמצעות android.enableR8.fullMode=true. במצב מלא, המערכת מבצעת אופטימיזציות חזקות יותר על ידי הנחות מחמירות יותר לגבי האופן שבו הקוד משתמש בהשתקפות ובתכונות דינמיות אחרות. השימוש ב-ProGuard מקטין את גודל האפליקציה ומשפר את הביצועים, אבל יכול להיות שיהיה צורך להוסיף כללי שמירה כדי למנוע את הסרת הקוד הנדרש.