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

‫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 הועברה לאפליקציה שמבוססת רק על Compose, גודל ה-APK ירד מ-3,034KB ל-2,966KB – ירידה של 68KB. ההפחתה הזו נבעה מהסרת יחסי תלות לא מנוצלים של View, כמו AppCompat ו-ConstraintLayout.

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

הוספת פיתוח נייטיב מגדילה את זמן ה-build של האפליקציה כי המהדר של פיתוח נייטיב מעבד את רכיבי ה-composable באפליקציה. התוצאות הבאות התקבלו באמצעות הכלי העצמאי 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 ועדכון כמה יחסי תלות לגרסאות העדכניות שלהם.

סיכום

שימוש בפיתוח נייטיב יגדיל את גודל ה-APK של האפליקציה וגם את זמן הבנייה של האפליקציה, בגלל תהליך הקימפול של קוד פיתוח נייטיב. עם זאת, צריך לשקול את הפשרות האלה מול היתרונות של פיתוח נייטיב, במיוחד בכל הקשור לעלייה בפרודוקטיביות של המפתחים כשמשתמשים בפיתוח נייטיב. לדוגמה, הצוות של חנות 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 אין אובייקטים מפורשים שניתן לעדכן כדי לצייר תצוגות. רכיבים בממשק המשתמש הם פונקציות קומפוזביליות פשוטות שהמידע שלהן נכתב בקומפוזיציה באופן שניתן להפעלה חוזרת. כך אפשר לצמצם את המעקב המפורש אחרי המצב, את הקצאות הזיכרון ואת הקריאות החוזרות (callbacks) רק לרכיבים הניתנים לשילוב שדורשים את התכונות האלה, במקום לדרוש אותם בכל התוספים של סוג View נתון.

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

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

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

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

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

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

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

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

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

צוות Jetpack Compose משתמש ב-Macrobenchmark גם כדי לעקוב אחרי רגרסיות ולבדוק את הביצועים בהשוואה לתצוגות בגרסאות שונות. במאמר בדיקות ביצועים של Hero מפורטות בדיקות ביצועים של הפעלה וגלילה שמשוות בין Compose לבין תצוגות באפליקציית Pokedex בקוד פתוח.

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

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