Độ ổn định trong Compose

Compose xem xét các kiểu là ổn định hoặc không ổn định. Một kiểu dữ liệu là ổn định khi là không thể thay đổi hoặc liệu Compose có thể biết liệu giá trị của thay đổi giữa các lần kết hợp lại. Một loại là không ổn định nếu Compose không biết liệu giá trị của nó đã thay đổi giữa các lần kết hợp lại.

Compose sử dụng độ ổn định của các tham số của một thành phần kết hợp để xác định xem liệu nó có có thể bỏ qua thành phần kết hợp trong quá trình kết hợp lại:

  • Tham số ổn định:Nếu một thành phần kết hợp có các tham số ổn định chưa đã thay đổi, Compose sẽ bỏ qua nó.
  • Tham số không ổn định: Nếu một thành phần kết hợp có tham số không ổn định, Compose sẽ luôn kết hợp lại khi kết hợp lại thành phần mẹ của thành phần.

Nếu ứng dụng của bạn có nhiều thành phần không ổn định một cách không cần thiết, thì Compose luôn kết hợp lại, bạn có thể quan sát thấy các vấn đề về hiệu suất và các vấn đề khác.

Tài liệu này trình bày chi tiết cách bạn có thể tăng độ ổn định của ứng dụng để cải thiện hiệu suất và trải nghiệm người dùng tổng thể.

Đối tượng bất biến

Các đoạn mã sau đây trình bày các nguyên tắc chung đằng sau sự ổn định và kết hợp lại.

Lớp Contact là lớp dữ liệu không thể thay đổi. Điều này là do tất cả tham số là các giá trị gốc được xác định bằng từ khoá val. Sau khi tạo của Contact, thì bạn không thể thay đổi giá trị các thuộc tính của đối tượng. Nếu bạn cố gắng làm như vậy, bạn sẽ tạo một đối tượng mới.

data class Contact(val name: String, val number: String)

Thành phần kết hợp ContactRow có tham số thuộc loại Contact.

@Composable
fun ContactRow(contact: Contact, modifier: Modifier = Modifier) {
   var selected by remember { mutableStateOf(false) }

   Row(modifier) {
      ContactDetails(contact)
      ToggleButton(selected, onToggled = { selected = !selected })
   }
}

Xem xét điều gì sẽ xảy ra khi người dùng nhấp vào nút bật tắt và selected thay đổi về trạng thái:

  1. Compose sẽ đánh giá xem có nên kết hợp lại mã bên trong ContactRow hay không.
  2. Nó thấy rằng đối số duy nhất cho ContactDetails thuộc loại Contact.
  3. Contact là lớp dữ liệu không thể thay đổi, Compose chắc chắn rằng không có các đối số cho ContactDetails đã thay đổi.
  4. Do đó, Compose bỏ qua ContactDetails và không kết hợp lại.
  5. Mặt khác, các đối số cho ToggleButton đã thay đổi và Compose sẽ kết hợp lại thành phần đó.

Đối tượng có thể thay đổi

Mặc dù ví dụ trước sử dụng đối tượng bất biến, nhưng bạn vẫn có thể tạo đối tượng đối tượng có thể thay đổi. Hãy xem xét đoạn mã sau:

data class Contact(var name: String, var number: String)

Vì mỗi tham số của Contact hiện là một var nên lớp này không thể thay đổi được nữa. Nếu các thuộc tính của Compose thay đổi, Compose sẽ không nhận biết được. Điều này là do Compose chỉ theo dõi các thay đổi đối với đối tượng Trạng thái Compose.

Compose coi một lớp như vậy là không ổn định. Compose không bỏ qua quá trình kết hợp lại các lớp không ổn định. Do đó, nếu Contact được xác định theo cách này, thì ContactRow trong ví dụ trước sẽ kết hợp lại bất cứ khi nào selected thay đổi.

Triển khai trong Compose

Việc cân nhắc cách Compose chính xác có thể giúp ích, mặc dù không quan trọng xác định hàm nào cần bỏ qua trong quá trình kết hợp lại.

Khi trình biên dịch Compose chạy trên mã của bạn, trình biên dịch này sẽ đánh dấu từng hàm và kiểu bằng một trong nhiều thẻ. Các thẻ này phản ánh cách Compose xử lý hàm hoặc nhập trong quá trình kết hợp lại.

Hàm

Compose có thể đánh dấu các hàm là skippable hoặc restartable. Xin lưu ý rằng việc này có thể đánh dấu một hàm là một, cả hai hoặc không phải là một trong hai hàm sau:

  • Có thể bỏ qua: Nếu trình biên dịch đánh dấu một thành phần kết hợp là có thể bỏ qua, thì Compose có thể bỏ qua trong quá trình kết hợp lại nếu tất cả các đối số của nó bằng nhau các giá trị trước đó.
  • Có thể khởi động lại: Một thành phần kết hợp có thể khởi động lại đóng vai trò là "phạm vi" ở đâu quá trình kết hợp lại có thể bắt đầu. Nói cách khác, hàm này có thể là một điểm mục nhập nơi Compose có thể bắt đầu thực thi lại mã để kết hợp lại sau các thay đổi về trạng thái.

Loại

Compose đánh dấu các loại là không thể thay đổi hoặc ổn định. Mỗi loại là một hoặc khác:

  • Không thể thay đổi: Compose đánh dấu một loại là không thể thay đổi nếu giá trị của loại các thuộc tính không bao giờ thay đổi và tất cả phương thức đều minh bạch về mặt tham chiếu.
    • Lưu ý rằng tất cả các loại nguyên hàm đều được đánh dấu là không thể thay đổi. Các cách này bao gồm String, IntFloat.
  • Ổn định: Cho biết loại có các thuộc tính có thể thay đổi sau khi tạo. Nếu và khi các thuộc tính đó thay đổi trong thời gian chạy, thì Compose sẽ biết được những thay đổi đó.

Độ ổn định của quá trình gỡ lỗi

Nếu ứng dụng của bạn đang kết hợp lại một thành phần kết hợp có tham số không thay đổi, trước tiên hãy kiểm tra định nghĩa của tham số đó để biết các tham số rõ ràng có thể thay đổi. Luôn soạn thư sẽ kết hợp lại một thành phần nếu bạn truyền một loại có thuộc tính var hoặc val sử dụng loại không ổn định đã biết.

Để biết thông tin chi tiết về cách chẩn đoán các vấn đề phức tạp về độ ổn định trong Compose, xem hướng dẫn Độ ổn định của gỡ lỗi.

Khắc phục các sự cố về độ ổn định

Để biết thông tin về cách đảm bảo tính ổn định cho quá trình triển khai Compose, hãy xem hướng dẫn Khắc phục sự cố về độ ổn định.

Tóm tắt

Nhìn chung, bạn cần lưu ý những điểm sau:

  • Tham số: Compose xác định độ ổn định của mỗi thông số của thành phần kết hợp nào để xác định thành phần kết hợp nào nên bỏ qua trong quá trình kết hợp lại.
  • Khắc phục ngay lập tức: Nếu bạn nhận thấy thành phần kết hợp không bị bỏ qua, và nhưng nó lại gây ra vấn đề về hiệu suất, thì bạn nên kiểm tra nguyên nhân rõ ràng như tham số var trước.
  • Báo cáo của trình biên dịch: Bạn có thể dùng báo cáo của trình biên dịch để xác định độ ổn định được dự đoán về lớp của mình.
  • Bộ sưu tập: Compose luôn xem các lớp bộ sưu tập là không ổn định, chẳng hạn như dưới dạng List, SetMap. Lý do là không thể đảm bảo rằng là bất biến. Thay vào đó, bạn có thể sử dụng các tập hợp không thể thay đổi Kotlinx hoặc chú thích các lớp học của bạn là @Immutable hoặc @Stable.
  • Các mô-đun khác: Compose luôn coi các mô-đun này đến từ đâu không ổn định các mô-đun mà trình biên dịch Compose không chạy. Gói các lớp trong giao diện người dùng các lớp mô hình nếu cần.

Tài liệu đọc thêm