Hiệu suất của Compose

Mục đích của Jetpack Compose là mang lại hiệu suất vượt trội ngay từ đầu. Trang này hướng dẫn bạn cách viết và định cấu hình ứng dụng để đạt được hiệu suất tốt nhất, đồng thời chỉ ra một số kiểu cấu hình cần tránh.

Trước khi đọc nội dung này, bạn có thể tìm hiểu các khái niệm chính về Compose trong Tư duy trong Compose.

Định cấu hình đúng cách cho ứng dụng của bạn

Nếu ứng dụng của bạn hoạt động kém hiệu quả, nghĩa là có thể đã xảy ra vấn đề với cấu hình. Việc đầu tiên nên làm là kiểm tra các tuỳ chọn cấu hình sau.

Tích hợp ở chế độ phát hành và sử dụng R8

Nếu bạn tìm thấy các sự cố về hiệu suất, hãy nhớ chạy ứng dụng ở chế độ phát hành. Chế độ gỡ lỗi rất hữu ích để phát hiện nhiều vấn đề, nhưng nó cũng khiến hiệu suất giảm đáng kể và còn gây khó khăn cho việc phát hiện các vấn đề khác về mã làm ảnh hưởng đến hiệu suất. Bạn cũng nên sử dụng Trình biên dịch R8 để xoá mã không cần thiết khỏi ứng dụng của mình. Theo mặc định, việc tạo ở chế độ phát hành sẽ tự động sử dụng trình biên dịch R8.

Sử dụng hồ sơ cơ sở

Compose được phân phối dưới dạng thư viện thay vì trở thành một phần của nền tảng Android. Phương pháp này cho phép chúng tôi thường xuyên cập nhật Compose và hỗ trợ các phiên bản Android cũ. Tuy nhiên, việc phân phối Compose dưới dạng thư viện sẽ gây ra hao tổn. Mã nền tảng Android đã được biên dịch và cài đặt trên thiết bị. Trong khi đó, thư viện cần được tải khi ứng dụng khởi động và diễn giải đúng thời điểm khi cần thiết. Thao tác này có thể làm chậm ứng dụng khi khởi động và bất cứ khi nào ứng dụng sử dụng tính năng thư viện lần đầu tiên.

Bạn có thể cải thiện hiệu suất bằng cách xác định hồ sơ cơ sở. Hồ sơ này xác định các lớp và phương thức cần thiết trong những hành trình trọng yếu của người dùng và được phân phối cùng với APK của ứng dụng. Trong quá trình cài đặt ứng dụng, ART biên dịch trước mã quan trọng đó, vì vậy, mã này đã sẵn sàng để sử dụng khi ứng dụng khởi chạy.

Không phải lúc nào bạn cũng dễ dàng xác định một hồ sơ cơ sở tốt, do vậy, theo mặc định, Compose đã có sẵn một hồ sơ cơ bản. Bạn có thể có được lợi ích này mà cần không phải làm gì. Tuy nhiên, nếu tự tạo hồ sơ thì hồ sơ bạn tạo có thể không thực sự cải thiện hiệu suất của ứng dụng. Bạn nên kiểm tra để xác minh hồ sơ đó hữu ích. Để làm việc đó, bạn nên viết các thử nghiệm Macrobenchmark cho ứng dụng và kiểm tra kết quả thử nghiệm khi viết và sửa đổi hồ sơ cơ sở của bạn. Để xem ví dụ về cách viết thử nghiệm Macrobenchmark cho giao diện người dùng trong Compose, hãy xem mẫu Macrobenchmark Compose.

Để biết thêm các phân tích chi tiết về tác động của chế độ phát hành, R8 và cấu hình cơ sở, vui lòng xem bài đăng trên blog với tiêu đề Tại sao bạn nên luôn thử nghiệm hiệu suất Compose trong bản phát hành?.

Ba giai đoạn Compose ảnh hưởng đến hiệu suất như thế nào

Như đã thảo luận trong Các giai đoạn trong Jetpack Compose, khi Compose cập nhật một khung, nó sẽ trải qua ba giai đoạn:

  • Thành phần: Compose xác định nội dung cần hiển thị – thành phần này chạy các hàm kết hợp và xây dựng cây giao diện người dùng.
  • Bố cục: Compose xác định kích thước và vị trí của từng phần tử trong cây giao diện người dùng.
  • Vẽ: Compose hiển thị các thành phần giao diện người dùng riêng lẻ.

Compose có thể bỏ qua bất kỳ giai đoạn nào trong số đó một cách thông minh nếu không cần thiết. Ví dụ: hãy giả sử một phần tử đồ hoạ hoán đổi giữa hai biểu tượng có cùng kích thước. Vì phần tử đó không thay đổi kích thước và không có phần tử nào trong cây giao diện người dùng được thêm hoặc xoá nên Compose có thể bỏ qua các giai đoạn thành phần và bố cục đồng thời chỉ vẽ lại một phần tử đó.

Tuy nhiên, một số lỗi lập trình có thể khiến Compose khó nhận biết được giai đoạn nào có thể bỏ qua một cách an toàn. Nếu có nghi ngờ, Compose sẽ chạy cả ba giai đoạn. Việc này có thể khiến giao diện người dùng của bạn chậm hơn mức cần thiết. Vì vậy, nhiều phương pháp hay nhất về hiệu suất xoay quanh việc giúp Compose bỏ qua các giai đoạn mà phương thức này không cần làm.

Có một vài nguyên tắc chung mà bạn có thể áp dụng để cải thiện hiệu suất chung.

Trước tiên, bất cứ khi nào có thể, hãy di chuyển các phép tính ra khỏi các hàm kết hợp. Bạn có thể cần chạy lại các hàm có khả năng kết hợp bất cứ khi nào giao diện người dùng thay đổi; mọi mã bạn đặt trong thành phần kết hợp sẽ được thực thi lại, có thể cho tất cả các khung của ảnh động. Vì vậy, bạn nên giới hạn mã của thành phần kết hợp ở cấp độ chỉ thực sự cần thiết để tạo giao diện người dùng.

Thứ hai, trạng thái trì hoãn khi đọc càng lâu càng tốt. Bằng việc chuyển trạng thái đọc cho thành phần kết hợp con hoặc giai đoạn sau, bạn có thể giảm thiểu thao tác kết hợp lại hoặc bỏ qua toàn bộ giai đoạn thành phần. Bạn có thể thực hiện việc này bằng cách truyền các hàm lambda thay vì giá trị trạng thái cho trạng thái thay đổi thường xuyên, và bằng cách ưu tiên các giá trị sửa đổi trên hàm lambda khi truyền ở trạng thái thường xuyên thay đổi. Bạn có thể xem ví dụ về kỹ thuật này trong phần Trì hoãn việc đọc càng lâu càng tốt.