Chế độ bỏ qua mạnh

Bỏ qua mạnh là một chế độ có trong trình biên dịch Compose. Khi được bật, tính năng này sẽ thay đổi hành vi của trình biên dịch theo hai cách:

  • Các thành phần kết hợp có tham số không ổn định sẽ trở thành có thể bỏ qua
  • Các lambda có bản ghi không ổn định sẽ được ghi nhớ

Bật chế độ bỏ qua hữu hiệu

Tính năng bỏ qua mạnh được bật theo mặc định trong Kotlin 2.0.20.

Để bật tính năng bỏ qua mạnh cho một mô-đun Gradle trong bản phát hành trước 2.0.20, hãy thêm tuỳ chọn sau vào khối composeCompiler của cấu hình Gradle:

android { ... }

composeCompiler {
   enableStrongSkippingMode = true
}

Khả năng bỏ qua thành phần kết hợp

Chế độ bỏ qua mạnh sẽ nới lỏng một số quy tắc độ ổn định mà trình biên dịch Compose thường áp dụng khi bỏ qua và các hàm có khả năng kết hợp. Theo mặc định, trình biên dịch Compose sẽ đánh dấu một hàm có khả năng kết hợp là có thể bỏ qua nếu tất cả đối số của hàm đó có giá trị ổn định. Chế độ bỏ qua hữu hiệu sẽ thay đổi điều này.

Khi bạn bật tính năng bỏ qua mạnh, tất cả các hàm có khả năng kết hợp có thể khởi động lại sẽ trở thành hàm có thể bỏ qua. Điều này áp dụng cho dù các thành phần có tham số không ổn định hay không. Các hàm có khả năng kết hợp không thể khởi động lại vẫn không thể bỏ qua.

Thời điểm bỏ qua

Để xác định xem có bỏ qua một thành phần kết hợp trong quá trình kết hợp lại hay không, Compose sẽ so sánh giá trị của mỗi tham số với giá trị trước đó. Loại so sánh phụ thuộc vào độ ổn định của tham số.

  • Các tham số không ổn định được so sánh bằng cách sử dụng tính chất bằng nhau của thực thể (===)
  • Các tham số ổn định được so sánh bằng cách sử dụng tính chất bằng nhau của đối tượng (Object.equals())

Nếu tất cả các tham số đều đáp ứng các yêu cầu này, thì Compose sẽ bỏ qua thành phần kết hợp trong quá trình kết hợp lại.

Bạn có thể muốn một thành phần kết hợp chọn không sử dụng tính năng bỏ qua mạnh. Tức là bạn có thể muốn một thành phần kết hợp có thể khởi động lại nhưng không thể bỏ qua. Trong trường hợp này, hãy sử dụng chú thích @NonSkippableComposable.

@NonSkippableComposable
@Composable
fun MyNonSkippableComposable {}

Chú giải các lớp là ổn định

Nếu bạn muốn một đối tượng sử dụng tính chất bằng nhau của đối tượng thay vì tính chất bằng nhau của thực thể, hãy tiếp tục chú thích lớp đã cho bằng @Stable. Ví dụ về trường hợp bạn có thể phải làm việc này là khi quan sát toàn bộ danh sách đối tượng, các nguồn dữ liệu như Room sẽ phân bổ đối tượng mới cho mọi mục trong danh sách bất cứ khi nào một trong các đối tượng đó thay đổi.

Ghi nhớ Lambda

Chế độ bỏ qua hữu hiệu cũng cho phép ghi nhớ nhiều lambda hơn trong các thành phần kết hợp. Khi bật tính năng bỏ qua mạnh, mọi lambda bên trong hàm có khả năng kết hợp sẽ tự động được ghi nhớ.

Ví dụ

Để ghi nhớ các lambda bên trong các thành phần kết hợp khi sử dụng tính năng bỏ qua mạnh, trình biên dịch sẽ gói lambda của bạn bằng lệnh gọi remember. Nó được khoá bằng các bản ghi của lambda.

Hãy xem xét trường hợp bạn có một lambda như trong ví dụ sau:

@Composable
fun MyComposable(unstableObject: Unstable, stableObject: Stable) {
    val lambda = {
        use(unstableObject)
        use(stableObject)
    }
}

Khi bật tính năng bỏ qua mạnh, trình biên dịch sẽ lưu hàm lambda vào bộ nhớ đệm bằng cách gói hàm đó trong lệnh gọi remember:

@Composable
fun MyComposable(unstableObject: Unstable, stableObject: Stable) {
    val lambda = remember(unstableObject, stableObject) {
        {
            use(unstableObject)
            use(stableObject)
        }
    }
}

Các khoá tuân theo các quy tắc so sánh giống như hàm có khả năng kết hợp. Thời gian chạy so sánh các khoá không ổn định bằng cách sử dụng tính chất bằng nhau của thực thể. Phương thức này so sánh các khoá ổn định bằng cách sử dụng tính chất bằng nhau của đối tượng.

Ghi nhớ và kết hợp lại

Tính năng tối ưu hoá này làm tăng đáng kể số lượng thành phần kết hợp mà thời gian chạy bỏ qua trong quá trình kết hợp lại. Nếu không có tính năng ghi nhớ, thời gian chạy có nhiều khả năng phân bổ một lambda mới cho bất kỳ thành phần kết hợp nào lấy tham số lambda trong quá trình kết hợp lại. Do đó, lambda mới có các tham số không bằng thành phần cuối cùng. Điều này dẫn đến việc kết hợp lại.

Tránh lưu vào bộ nhớ đệm

Nếu bạn có một lambda mà bạn không muốn lưu vào bộ nhớ đệm, hãy sử dụng chú thích @DontMemoize.

val lambda = @DontMemoize {
    ...
}

Kích thước APK

Khi biên dịch, các Thành phần kết hợp có thể bỏ qua sẽ tạo ra nhiều mã hơn so với các thành phần kết hợp không thể bỏ qua. Khi bạn bật tính năng bỏ qua mạnh, trình biên dịch sẽ đánh dấu gần như tất cả các thành phần kết hợp là có thể bỏ qua và gói tất cả các lambda trong một remember{...}. Do đó, việc bật chế độ bỏ qua hữu hiệu sẽ tác động rất nhỏ đến kích thước APK của ứng dụng.

Việc bật tính năng bỏ qua mạnh trong Now In Android đã làm tăng kích thước APK thêm 4 kB. Sự khác biệt về kích thước phụ thuộc phần lớn vào số lượng thành phần kết hợp không thể bỏ qua trước đây có trong ứng dụng nhất định nhưng sẽ tương đối nhỏ.