אופטימיזציה של היררכיות פריסה

אפשר לנסות את הדרך של כתיבת הודעה
‫Jetpack Compose היא ערכת הכלים המומלצת לבניית ממשק משתמש ב-Android. איך עובדים עם פריסות בכתיבת אימייל

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

במאמר הזה מוסבר איך להשתמש ב-Layout Inspector וב-lint כדי לבדוק ולבצע אופטימיזציה של הפריסה.

בדיקת הפריסה

ערכת הכלים של Android SDK כוללת את הכלי Layout Inspector, שמאפשר לכם לנתח את הפריסה בזמן שהאפליקציה פועלת. הכלי הזה עוזר לכם לגלות חוסר יעילות בביצועים של הפריסה.

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

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

תמונה שבה רואים פריט אחד ברשימה: תמונה אחת ושני טקסטים שמסודרים אנכית
איור 1. פריסת קונספט של פריט ב-RecyclerView.

ב-Layout Inspector מוצגת רשימה של מכשירים זמינים והרכיבים שפועלים בהם. בוחרים את הרכיב בכרטיסייה Windows ולוחצים על Layout Inspector כדי לראות את ההיררכיה של הפריסה של הרכיב שנבחר. לדוגמה, באיור 2 מוצגת הפריסה של פריט הרשימה שמוצג באיור 1.

תמונה שבה מוצג Layout Inspector והקומפוזיציה של LinearLayout
איור 2. היררכיית הפריסה של הפריסה באיור 1, באמצעות מופעים מוטמעים של LinearLayout.

שינוי הפריסה

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

    <androidx.constraintlayout.widget.ConstraintLayout
      xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:app="http://schemas.android.com/apk/res-auto"
      xmlns:tools="http://schemas.android.com/tools"
      android:id="@+id/root"
      android:layout_width="match_parent"
      android:layout_height="52dp"
      android:background="#e4e6e4"
      android:padding="4dp">

      <ImageView
          android:id="@+id/image"
          android:layout_width="48dp"
          android:layout_height="48dp"
          android:background="#5c5c74"
          android:contentDescription="An example box"
          app:layout_constraintBottom_toBottomOf="parent"
          app:layout_constraintStart_toStartOf="parent"
          app:layout_constraintTop_toTopOf="parent" />

      <TextView
          android:id="@+id/title"
          android:layout_width="0dp"
          android:layout_height="0dp"
          android:layout_marginStart="4dp"
          android:background="#745c74"
          app:layout_constraintBottom_toTopOf="@+id/subtitle"
          app:layout_constraintEnd_toEndOf="parent"
          app:layout_constraintStart_toEndOf="@id/image"
          app:layout_constraintTop_toTopOf="parent" />

      <TextView
          android:id="@+id/subtitle"
          android:layout_width="0dp"
          android:layout_height="0dp"
          android:background="#7e8d6e"
          app:layout_constraintBottom_toBottomOf="parent"
          app:layout_constraintEnd_toEndOf="parent"
          app:layout_constraintStart_toStartOf="@id/title"
          app:layout_constraintTop_toBottomOf="@+id/title" />
  </androidx.constraintlayout.widget.ConstraintLayout>
    

בדיקה של הפריסה החדשה נראית כך:

תמונה שבה מוצג Layout Inspector בתלת-ממד
איור 3. מצב תלת-ממד של Layout Inspector.

היתרונות של הפריסה הזו הם רבים, כי היא משמשת לכל פריט ברשימה.

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

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

שימוש ב-lint

מומלץ להריץ את הכלי lint בקובצי הפריסה כדי לחפש אופטימיזציות אפשריות של היררכיית התצוגה. ‫Lint מחליף את הכלי layoutopt ויש לו פונקציונליות רחבה יותר. אלה כמה דוגמאות לכללי lint:

  • שימוש ב-compound drawables. אפשר לטפל ב-LinearLayout שמכיל ImageView ו-TextView בצורה יעילה יותר כ-drawable מורכב.
  • מיזוג פריים השורש. אם רכיב הבסיס של פריסת התוכן הוא תג FrameLayout שלא מספק רקע או מרווח פנימי, אפשר להחליף אותו בתג מיזוג, שהוא קצת יותר יעיל.
  • להסיר עלים מיותרים. אפשר להסיר פריסה שאין לה צאצאים או שאין לה רקע – כי היא לא נראית – כדי ליצור היררכיית פריסה שטוחה ויעילה יותר.
  • הסרה של הורים לא שימושיים. אפשר להסיר פריסה עם רכיב צאצא שאין לו רכיבי אחים, שהוא לא ScrollView או פריסת בסיס, ואין לו רקע. אפשר גם להעביר את תצוגת הילד ישירות אל תצוגת ההורה כדי ליצור היררכיית פריסה שטוחה ויעילה יותר.
  • אל תשתמשו בפריסות עמוקות. פריסות עם יותר מדי קינון פוגעות בביצועים. כדאי להשתמש בפריסות שטוחות יותר, כמו ConstraintLayout, כדי לשפר את הביצועים. עומק ברירת המחדל המקסימלי לבדיקות lint הוא 10.

יתרון נוסף של כלי ה-lint הוא השילוב שלו ב-Android Studio. ‫Lint פועל אוטומטית בכל פעם שמקמפלים את התוכנית. ב-Android Studio אפשר גם להריץ בדיקות כלי לאיתור שגיאות בקוד (lint) עבור וריאנט build ספציפי או עבור כל וריאנטים ה-build.

אפשר גם לנהל פרופילים של בדיקות ולהגדיר בדיקות ב-Android Studio באמצעות האפשרות File > Settings > Project Settings (קובץ > הגדרות > הגדרות פרויקט). יופיע הדף Inspection Configuration (הגדרת בדיקה) עם הבדיקות הנתמכות:

תמונה שרואים בה את התפריט &#39;בדיקות&#39; ב-Android Studio
איור 4. דף הגדרות הבדיקה.

‫Lint יכול לתקן באופן אוטומטי חלק מהבעיות, לספק הצעות לבעיות אחרות ולעבור ישירות לקוד הבעייתי לבדיקה.

מידע נוסף זמין במאמרים בנושא פריסות ומשאב פריסה.