Tối ưu hoá hệ phân cấp bố cục

Thử cách sử dụng Compose
Jetpack Compose là bộ công cụ giao diện người dùng được đề xuất cho Android. Tìm hiểu cách sử dụng bố cục trong ứng dụng Compose.

Có một quan niệm sai lầm phổ biến là việc sử dụng cấu trúc bố cục cơ bản sẽ mang lại bố cục hiệu quả nhất. Tuy nhiên, mỗi tiện ích và bố cục bạn thêm vào ứng dụng sẽ yêu cầu khởi chạy, bố cục và vẽ. Chẳng hạn như việc sử dụng các thực thể lồng nhau của LinearLayout có thể dẫn đến một hệ phân cấp khung hiển thị quá sâu. Hơn nữa, việc lồng nhiều thực thể của LinearLayout sử dụng thông số layout_weight có thể rất tốn kém, vì mỗi thành phần con cần được đo lường hai lần. Điều này đặc biệt quan trọng khi bố cục được tăng cường nhiều lần, chẳng hạn như khi dùng trong RecyclerView.

Tài liệu này cho biết cách sử dụng Layout Inspectorlint để kiểm tra và tối ưu hoá bố cục.

Kiểm tra bố cục

Bộ công cụ SDK Android bao gồm công cụ Layout Inspector, cho phép bạn phân tích bố cục trong khi ứng dụng đang chạy. Khi sử dụng công cụ này, bạn sẽ phát hiện các điểm kém hiệu quả trong hiệu suất bố cục.

Layout Inspector cho phép bạn chọn các quy trình đang chạy trên một thiết bị đã kết nối hoặc trình mô phỏng, sau đó hiển thị cây bố cục. Đèn giao thông trên mỗi khối đại diện cho hiệu suất của Measure, Layout và Draw, giúp bạn xác định các vấn đề tiềm ẩn.

Ví dụ: hình 1 cho thấy bố cục được dùng như một mục trong RecyclerView. Bố cục này hiển thị một hình ảnh bitmap nhỏ ở bên trái và hai mục văn bản xếp chồng ở bên phải. Điều đặc biệt quan trọng là bố cục được tăng cường nhiều lần như thế này phải được tối ưu hoá, vì lợi ích về hiệu suất sẽ được nhân lên.

Hình ảnh cho thấy một mục trong danh sách: một hình ảnh và 2 văn bản được căn chỉnh theo chiều dọc
Hình 1. Bố cục khái niệm cho một mục trong RecyclerView.

Layout Inspector hiển thị danh sách các thiết bị có sẵn và thành phần đang chạy của các thiết bị đó. Chọn thành phần của bạn trên thẻ Windows (Cửa sổ) rồi nhấp vào Layout Inspector (Trình kiểm tra bố cục) để xem hệ phân cấp bố cục của thành phần đã chọn. Ví dụ: Hình 2 cho thấy bố cục của mục danh sách được minh hoạ trong hình 1.

Hình ảnh cho thấy Layout Inspector và thành phần LinearLayout
Hình 2. Hệ phân cấp bố cục cho bố cục trong hình 1, sử dụng các thực thể lồng nhau của LinearLayout.

Chỉnh sửa bố cục

Vì hiệu suất bố cục phía trước bị chậm lại do LinearLayout lồng ghép, bạn có thể cải thiện hiệu suất bằng cách làm phẳng bố cục, nói cách khác là làm cho bố cục nông và rộng, thay vì hẹp và sâu. ConstraintLayout là nút gốc cho phép các bố cục như vậy. Khi bạn chuyển đổi thiết kế này để sử dụng ConstraintLayout, bố cục sẽ trở thành hệ phân cấp hai cấp:

    <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>
    

Việc kiểm tra bố cục mới sẽ có dạng như sau:

Hình ảnh cho thấy Layout Inspector 3D
Hình 3. Chế độ 3D trong Layout Inspector.

Lợi ích của việc này được nhân lên nhiều lần vì bố cục này được sử dụng cho mọi mục trong danh sách.

Hầu hết sự khác biệt là do việc sử dụng layout_weight trong thiết kế LinearLayout, điều này có thể làm chậm quá trình đo lường. Đây là một ví dụ về cách sử dụng thích hợp của mỗi bố cục. Hãy cân nhắc kỹ xem việc sử dụng trọng số bố cục có cần thiết hay không.

Trong một số bố cục phức tạp, hệ thống có thể lãng phí công sức đo lường cùng một phần tử trên giao diện người dùng nhiều lần. Hiện tượng này được gọi là đánh thuế hai lần. Để biết thêm thông tin về việc đánh thuế hai lần và cách ngăn chặn tình trạng này, hãy xem bài viết Hiệu suất và hệ phân cấp khung hiển thị.

Sử dụng công cụ tìm lỗi mã nguồn

Bạn nên chạy công cụ tìm lỗi mã nguồn (lint) trên các tệp bố cục để tìm các cách tối ưu hoá hệ phân cấp khung hiển thị. Công cụ tìm lỗi mã nguồn sẽ thay thế công cụ layoutopt và có nhiều chức năng hơn. Sau đây là ví dụ về quy tắc tìm lỗi mã nguồn:

  • Sử dụng các đối tượng có thể vẽ phức hợp. Bạn có thể xử lý LinearLayout chứa ImageViewTextView hiệu quả hơn dưới dạng một đối tượng có thể vẽ phức hợp.
  • Hợp nhất khung gốc. Nếu gốc của bố cục là một FrameLayout không cung cấp nền hoặc khoảng đệm, thì bạn có thể thay thế bằng một thẻ hợp nhất. Cách này hiệu quả hơn một chút.
  • Hãy cắt bỏ những chiếc lá vô dụng. Bạn có thể xoá bố cục không có nền con hoặc không có nền (vì bố cục đó không hiển thị) để có hệ phân cấp bố cục phẳng và hiệu quả hơn.
  • Xoá những cha mẹ vô dụng. Bạn có thể xoá một bố cục có bố cục con không có anh em, không phải là ScrollView hoặc bố cục gốc và không có nền. Bạn cũng có thể di chuyển thành phần hiển thị con trực tiếp vào thành phần mẹ để có hệ phân cấp bố cục phẳng và hiệu quả hơn.
  • Tránh dùng bố cục sâu. Bố cục có quá nhiều lồng ghép sẽ gây ảnh hưởng không tốt đến hiệu suất. Hãy cân nhắc dùng bố cục phẳng hơn, chẳng hạn như ConstraintLayout để cải thiện hiệu suất. Chiều sâu tối đa mặc định để kiểm tra tìm lỗi mã nguồn là 10.

Một lợi ích khác của công cụ tìm lỗi mã nguồn là công cụ này được tích hợp vào Android Studio. Công cụ tìm lỗi mã nguồn sẽ tự động chạy bất cứ khi nào bạn biên dịch chương trình. Với Android Studio, bạn cũng có thể chạy các yêu cầu kiểm tra tìm lỗi mã nguồn cho một biến thể bản dựng cụ thể hoặc cho tất cả các biến thể bản dựng.

Bạn cũng có thể quản lý hồ sơ kiểm tra và định cấu hình yêu cầu kiểm tra trong Android Studio bằng tuỳ chọn File > Settings > Project Settings (Tệp > Cài đặt > Cài đặt dự án). Trang Cấu hình kiểm tra sẽ xuất hiện với các yêu cầu kiểm tra được hỗ trợ:

Hình ảnh minh hoạ trình đơn Inspections (Kiểm tra) của Android Studio
Hình 4. Trang Cấu hình kiểm tra.

Công cụ tìm lỗi mã nguồn có thể tự động khắc phục một số vấn đề, đưa ra đề xuất cho người khác và chuyển thẳng đến mã vi phạm để xem xét.

Để biết thêm thông tin, hãy xem bài viết Bố cụcTài nguyên bố cục.