השוואה בין מדדי 'כתיבה' ו'צפייה'

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

גודל ה-APK וזמני הבנייה

בקטע הזה נסביר על ההשפעה על גודל ה-APK וזמן ה-build באמצעות האפליקציה לדוגמה Sunflower – אפליקציה שמדגימה שיטות מומלצות להעברת אפליקציה מבוססת-View לפיתוח נייטיב.

גודל ה-APK

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

צפיות בלבד שילוב של Views ופיתוח נייטיב כתיבה בלבד
גודל הורדה ‫2,252KB 3,034 KB 2,966 KB

בפעם הראשונה שהוספנו את Compose ל-Sunflower, גודל ה-APK גדל מ-2,252KB ל-3,034KB – עלייה של 782KB. קובץ ה-APK שנוצר כלל את ממשק המשתמש שנבנה באמצעות שילוב של Views ופיתוח נייטיב. העלייה הזו צפויה כי נוספו עוד יחסי תלות ל-Sunflower.

לעומת זאת, כשהאפליקציה Sunflower הועברה לפיתוח נייטיב בלבד, גודל ה-APK ירד מ-3,034KB ל-2,966KB – ירידה של 68KB. ההפחתה הזו נבעה מהסרת יחסי תלות לא מנוצלים של View, כמו AppCompat ו-ConstraintLayout.

משך זמן של תהליך build

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

gradle-profiler --benchmark --project-dir . :app:assembleDebug
צפיות בלבד שילוב של Views ופיתוח נייטיב כתיבה בלבד
משך זמן ממוצע של תהליך build 299.47 אלפיות השנייה ‫399.09 אלפיות השנייה ‫342.16 אלפיות השנייה

כשמוסיפים את Compose ל-Sunflower בפעם הראשונה, זמן ה-build הממוצע עולה מ-299 אלפיות השנייה ל-399 אלפיות השנייה – עלייה של 100 אלפיות השנייה. משך הזמן הזה נובע מכך שהקומפיילר של Compose מבצע משימות נוספות כדי להמיר את קוד Compose שמוגדר בפרויקט.

לעומת זאת, זמן ה-build הממוצע ירד ל-342 אלפיות השנייה, ירידה של 57 אלפיות השנייה, כשההעברה של Sunflower ל-Compose הושלמה. ההפחתה הזו יכולה לנבוע מכמה גורמים שמפחיתים את זמן ה-build, כמו הסרת קישור נתונים, העברת יחסי תלות שמשתמשים ב-kapt ל-KSP ועדכון כמה יחסי תלות לגרסאות העדכניות שלהם.

סיכום

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

אפשר לקרוא עוד תיאורי מקרה במאמר הטמעת Compose בצוותים.

ביצועים בזמן ריצה

בקטע הזה נסביר על נושאים שקשורים לביצועים בזמן הריצה ב-Jetpack Compose, כדי לעזור לכם להבין את ההבדלים בין הביצועים של Jetpack Compose לבין הביצועים של מערכת View, ואיך אפשר למדוד אותם.

שינוי חכם של הקומפוזיציה

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

פרופילים של Baseline

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

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

השוואה למערכת View

ל-Jetpack Compose יש הרבה שיפורים בהשוואה למערכת View. השיפורים האלה מתוארים בקטעים הבאים.

הכול מרחיב את View

כל View שמוצג במסך, כמו TextView,‏ Button או ImageView, דורש הקצאות זיכרון, מעקב מפורש אחרי המצב וקריאות חוזרות (callbacks) שונות כדי לתמוך בכל תרחישי השימוש. בנוסף, הבעלים של View בהתאמה אישית צריך להטמיע לוגיקה מפורשת כדי למנוע שרטוט מחדש כשאין צורך בכך – לדוגמה, לעיבוד נתונים חוזר.

ב-Jetpack Compose יש כמה דרכים לטפל בבעיה הזו. ב-Compose אין אובייקטים מפורשים שאפשר לעדכן כדי לצייר תצוגות. רכיבים בממשק המשתמש הם פונקציות קומפוזביליות פשוטות שהמידע שלהן נכתב בקומפוזיציה באופן שניתן להפעלה חוזרת. כך אפשר לצמצם את המעקב המפורש אחרי המצב, את הקצאות הזיכרון ואת הקריאות החוזרות (callback) רק לפונקציות ה-composable שדורשות את התכונות האלה, במקום לדרוש אותן בכל התוספים של סוג View נתון.

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

מספר מעברים על הפריסה

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

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

צפייה בביצועי ההפעלה

מערכת התצוגה צריכה להרחיב את פריסות ה-XML כשהיא מציגה פריסה מסוימת בפעם הראשונה. העלות הזו נחסכת ב-Jetpack Compose כי הפריסות נכתבות ב-Kotlin ומקומפלות כמו שאר האפליקציה.

הערכת ביצועים של Compose

ב-Jetpack Compose 1.0, יש הבדלים משמעותיים בין הביצועים של אפליקציה במצב debug לבין הביצועים שלה במצב release. כדי לקבל תזמונים מייצגים, תמיד צריך להשתמש ב-build של release במקום ב-debug כשמנתחים את פרופיל האפליקציה.

כדי לבדוק את הביצועים של קוד Jetpack Compose, אתם יכולים להשתמש בספריית Jetpack Macrobenchmark. כדי ללמוד איך להשתמש בו עם Jetpack Compose, עיינו בפרויקט MacrobenchmarkSample.

הצוות של Jetpack Compose משתמש גם ב-Macrobenchmark כדי לזהות רגרסיות שעלולות להתרחש. לדוגמה, אפשר לעיין בבדיקת הביצועים של LazyColumn ובמרכז הבקרה שלה כדי לעקוב אחרי רגרסיות.

התקנת פרופיל Compose

מכיוון ש-Jetpack Compose היא ספרייה נפרדת, היא לא נהנית מ-Zygote שטוען מראש את המחלקות ואת פריטי ה-drawable של ערכת הכלים של ממשק המשתמש של מערכת View. ב-Jetpack Compose 1.0, התקנת הפרופיל משמשת לגרסאות build להפצה. מתקיני פרופילים מאפשרים לאפליקציות לציין קוד קריטי שצריך לעבור הידור מראש (AOT) בזמן ההתקנה. ב-Compose יש כללי התקנה של פרופילים שמקצרים את זמן ההפעלה ומפחיתים את הבעיות בממשק (jank) באפליקציות של Compose.