מקרים לדוגמה

איך Reddit השתמש בכלי האופטימיזציה R8 כדי לשפר את הביצועים באופן משמעותי

משך הקריאה: 4 דקות
Ben Weiss
מהנדס קשרי מפתחים

בעולם של היום, שבו האפליקציות לנייד הן במרכז הבמה, חוויית משתמש חלקה היא לא רק תכונה – היא הכרחית. זמני טעינה ארוכים, ממשקים שלא מגיבים וחוסר יציבות יכולים להוות מכשולים משמעותיים למעורבות המשתמשים ולשימור שלהם. במהלך העבודה עם צוות קשרי המפתחים של Android, צוות ההנדסה ב-Reddit השתמש בציון הביצועים של האפליקציה כדי להעריך את האפליקציה. אחרי הערכת הביצועים, הצוות זיהה פוטנציאל שיפור משמעותי והחליט לבצע את השלבים להפעלת היכולות המלאות של R8, הכלי לאופטימיזציה של אפליקציות ל-Android. היוזמה הממוקדת הזו הובילה לשיפורים משמעותיים בזמני ההפעלה, לצמצום מספר הפריימים האיטיים או הקפואים ולצמצום מספר שגיאות ה-ANR, ולעלייה כללית בדירוגים בחנות Play. במקרה לדוגמה הזה מפורט איך Reddit השיגה את התוצאות המרשימות האלה.

איך הכלי R8 Optimizer עזר ל-Reddit

כלי האופטימיזציה R8 הוא כלי בסיסי לאופטימיזציה של הביצועים ב-Android. יש כמה שלבים לשיפור הביצועים של האפליקציה.נסקור בקצרה את השלבים שהכי משפיעים על הביצועים.

  • Tree shaking הוא השלב הכי חשוב להקטנת הגודל של האפליקציה. כאן, קוד שלא נמצא בשימוש בתלות של האפליקציה ובאפליקציה עצמה מוסר.
  • הטמעה של שיטה מחליפה קריאות לשיטה בקוד בפועל, וכך משפרת את הביצועים של האפליקציה.
  • מיזוג כיתות ואסטרטגיות אחרות מיושמות כדי שהקוד יהיה קומפקטי יותר. בשלב הזה כבר לא מדובר בקוד מקור שקריא לבני אדם, אלא בקוד שעבר קומפילציה ופועל במהירות. לכן, הפשטות כמו ממשקים או היררכיות של מחלקות לא חשובות כאן ויוסרו.
  • מזעור מזהים משנה את השמות של מחלקות, שדות ושיטות לשמות קצרים יותר וחסרי משמעות. לכן, במקום MyDataModel, יכול להיות שתקבלו כיתה בשם a.
  • כיווץ משאבים מסיר משאבים שלא נמצאים בשימוש, כמו קובצי XML ומשאבי drawable, כדי להקטין עוד יותר את גודל האפליקציה.
image.png

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

מנתונים קשים לשביעות רצון המשתמשים: זיהוי הצלחה בסביבת הייצור

ב-Reddit נהנו מתוצאות ביצועים משופרות מיד אחרי השקת גרסה חדשה של האפליקציה למשתמשים. בעזרת Android Vitals ו-Crashlytics, הצליחו ב-Reddit לאסוף מדדי ביצועים במכשירים אמיתיים עם משתמשים בפועל, וכך להשוות בין הגרסה החדשה לגרסאות קודמות.

image.png

איך R8 שיפר את ביצועי האפליקציה של Reddit

הצוות הבחין בהפעלה מהירה יותר ב-40% במצב התחלתי (cold start), בירידה של 30% במספר השגיאות מסוג 'האפליקציה לא מגיבה' (ANR), בשיפור של 25% בעיבוד הפריימים ובירידה של 14% בגודל האפליקציה.

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

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

image.png

Drew Heavner: "Enabling R8's full potential tool less than 2 weeks"

הדבר המרשים ביותר הוא שההישג הזה הושג באמצעות מאמץ ממוקד. דרו האבנר (Drew Heavner), מהנדס תוכנה בצוות של Reddit שעבד על היוזמה הזו, ציין שהטמעת השינויים כדי לממש את הפוטנציאל המלא של R8 נמשכה פחות משבועיים.

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

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

פרופילים של Baseline מעבירים ביעילות את שלבי ההידור Just in Time (JIT) ממכשירי המשתמשים למכונות של המפתחים. הוכח שהקוד המהודר שנוצר מראש (AOT) מפחית את זמן ההפעלה ואת בעיות העיבוד.

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

Jetpack Macrobenchmark היה הכלי המרכזי בשלב הזה, והוא אפשר מדידה מדויקת של אינטראקציות משתמשים בסביבה מבוקרת. כדי לדמות את התהליך שעובר המשתמש, הם השתמשו ב-UIAutomator API כדי ליצור בדיקה שבה האפליקציה נפתחת, מתבצעת גלילה למטה שלוש פעמים ואז גלילה חזרה למעלה.

בסופו של דבר, כדי לכתוב את ההשוואה לשוק היה צריך רק את הנתונים הבאים:

uiAutomator {

  startApp(REDDIT)

  repeat(3) {

    onView { isScrollable }.fling(Direction.DOWN) }

  repeat(3) {

    onView {isScrollable }.fling(Direction.UP)

  }

}

נתוני ההשוואה אישרו את התצפיות בשטח וסיפקו תובנות מעמיקות יותר. האפליקציה שעברה אופטימיזציה מלאה נפתחה במהירות גבוהה ב-55% והמשתמשים יכלו להתחיל לגלוש במהירות גבוהה ב-18% . בנוסף, באפליקציה שעברה אופטימיזציה נרשמה ירידה של שני שלישים במספר המקרים של הידור בזמן אמת (JIT) וירידה של שליש בזמן ההידור בזמן אמת. הרינדור של הפריימים השתפר, וכתוצאה מכך רונדרו 19% יותר פריימים במהלך התהליך שעובר המשתמש בהשוואה לביצועים הקודמים. בסופו של דבר, גודל האפליקציה הוקטן ביותר משליש.

image.png

שיפורים כלליים בביצועים של Reddit

אפשר למדוד את זמן ההידור של JIT באמצעות מדד מותאם אישית של קטע מעקב של Macrobenchmark, כמו זה:

val jitCompilationMetric = TraceSectionMetric("JIT Compiling %", label = "JIT compilation")

הפעלת הטכנולוגיה שמאחורי השינוי: R8

כדי להפעיל את R8 במצב מלא, מגדירים את הקובץ app/build.gradle.kts על ידי הגדרת minifyEnabled ו-shrinkResources ל-true בסוג ה-build של גרסת build להפצה.

android {

    ...

    buildTypes {

        release {

            isMinifyEnabled = true

            isShrinkResources = true

            proguardFiles(

                getDefaultProguardFile("proguard-android-optimize.txt"),

                "keep-rules.pro",

            )

        }

    }

}

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

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

איך מיישמים באפליקציה את הדוגמה של Reddit

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

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

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

נכתב על ידי:

להמשך הקריאה