Case Studies

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

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

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

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

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

  • Tree shaking הוא השלב הכי חשוב להקטנת הגודל של האפליקציה. כאן, קוד שלא נעשה בו שימוש מהתלויות של האפליקציה ומהאפליקציה עצמה מוסר.
  • Method inlining מחליף קריאות למתודות בקוד בפועל, וכך משפר את הביצועים של האפליקציה.
  • מיזוג כיתות ואסטרטגיות אחרות מיושמות כדי שהקוד יהיה קומפקטי יותר. בשלב הזה, כבר לא מדובר בקוד מקור שקריא לבני אדם, אלא בקוד שעבר קומפילציה ופועל במהירות. לכן, הפשטות כמו ממשקים או היררכיות של כיתות לא חשובות כאן ויוסרו.
  • מזעור מזהים משנה את השמות של מחלקות, שדות ושיטות לשמות קצרים יותר וחסרי משמעות. לכן, במקום 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"

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

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

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

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

כשיוצרים חבילה של אפליקציה, כלי ה-dexer‏ d8 לוקח מחלקות ושיטות ובונה את קובצי ה-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 לאופטימיזציה.

נכתב על ידי:

להמשך הקריאה