Tạo Hồ sơ cơ sở

Tự động tạo hồ sơ cho mọi bản phát hành ứng dụng bằng thư viện Jetpack MacrobenchmarkBaselineProfileRule. Bạn nên sử dụng com.android.tools.build:gradle:8.0.0 trở lên, cùng với các cải tiến về bản dựng khi dùng Hồ sơ cơ sở.

Dưới đây là các bước chung để tạo một Hồ sơ cơ sở mới:

  1. Thiết lập mô-đun Hồ sơ cơ sở.
  2. Xác định chương trình kiểm thử JUnit giúp tạo Hồ sơ cơ sở.
  3. Thêm Hành trình trọng yếu của người dùng (CUJ) mà bạn muốn tối ưu hoá.
  4. Tạo Hồ sơ cơ sở.

Sau khi bạn tạo Hồ sơ cơ sở, hãy đo điểm chuẩn cho hồ sơ đó bằng một thiết bị thực để đo lường mức cải thiện tốc độ.

Tạo Hồ sơ cơ sở mới bằng AGP 8.2 trở lên

Cách dễ nhất để tạo Hồ sơ cơ sở mới là sử dụng mẫu mô-đun Hồ sơ cơ sở có trong Android Studio Iguana và Trình bổ trợ Android cho Gradle (AGP) 8.2 trở lên.

Mẫu mô-đun trình tạo Hồ sơ cơ sở của Android Studio sẽ tự động tạo một mô-đun mới để tạo và đo điểm chuẩn Hồ sơ cơ sở. Khi chạy mẫu này sẽ tạo hầu hết cấu hình bản dựng điển hình, chức năng tạo Hồ sơ cơ sở và mã xác minh. Mẫu này sẽ tạo mã để tạo và đo điểm chuẩn cho Hồ sơ cơ sở để đo lường ứng dụng lúc khởi động.

Thiết lập mô-đun Hồ sơ cơ sở

Để chạy mẫu mô-đun Hồ sơ cơ sở, hãy làm theo các bước sau:

  1. Chọn File > New > New Module (Tệp > Mới > Mô-đun mới)
  2. Chọn mẫu trình tạo Hồ sơ cơ sở trong bảng điều khiển Mẫu rồi định cấu hình mẫu đó:
    Hình 1. Mẫu mô-đun trình tạo Hồ sơ cơ sở.

    Trong mẫu có các trường như sau:

    • Target application (Ứng dụng mục tiêu): xác định xem Hồ sơ cơ sở sẽ được tạo cho ứng dụng nào. Khi dự án của bạn chỉ có một mô-đun ứng dụng duy nhất, thì danh sách này chỉ có một mục duy nhất.
    • Module name (Tên mô-đun): tên bạn muốn cho mô-đun Hồ sơ cơ sở được tạo.
    • Package name (Tên gói): tên gói bạn muốn cho mô-đun Hồ sơ cơ sở.
    • Language (Ngôn ngữ): bạn muốn tạo mã Kotlin hay Java.
    • Build configuration language (Ngôn ngữ cấu hình bản dựng): bạn muốn sử dụng Tập lệnh Kotlin (KTS) hay Groovy làm tập lệnh cấu hình bản dựng.
    • Sử dụng thiết bị do Gradle quản lý: cho dù bạn có đang sử dụng thiết bị do Gradle quản lý để kiểm thử ứng dụng của mình hay không.
  3. Nhấp vào Finish (Hoàn tất) và mô-đun mới sẽ được tạo. Nếu đang sử dụng chế độ kiểm soát nguồn, có thể bạn sẽ được nhắc thêm các tệp mô-đun mới tạo vào chế độ kiểm soát nguồn.

Xác định trình tạo Hồ sơ cơ sở

Mô-đun mới tạo chứa các chương trình kiểm thử cho cả việc tạo và đo điểm chuẩn Hồ sơ cơ sở, đồng thời chỉ kiểm thử quy trình khởi động ứng dụng cơ bản. Bạn nên tăng cường các tính năng này để đưa CUJ và quy trình khởi động nâng cao vào. Đảm bảo rằng mọi kiểm thử liên quan đến quá trình khởi động ứng dụng đều nằm trong khối rule với includeInStartupProfile được đặt thành true; ngược lại, để đạt được hiệu suất tối ưu, hãy đảm bảo rằng mọi kiểm thử không liên quan đến quá trình khởi động ứng dụng đều không được đưa vào Hồ sơ khởi động. Tính năng tối ưu hoá quá trình khởi động ứng dụng được dùng để xác định một phần đặc biệt của Hồ sơ cơ sở có tên là Hồ sơ khởi động.

Điều này tạo thuận lợi cho khả năng bảo trì, nếu bạn rút các CUJ này ra khỏi Hồ sơ cơ sở đã tạo và mã điểm chuẩn để có thể sử dụng cho cả hai. Điều này nghĩa là các thay đổi đối với CUJ sẽ được sử dụng một cách nhất quán.

Tạo và cài đặt Hồ sơ cơ sở

Mẫu mô-đun Hồ sơ cơ sở sẽ thêm một cấu hình chạy mới để tạo Hồ sơ cơ sở. Nếu bạn có nhiều phiên bản sản phẩm, Android Studio sẽ tạo nhiều cấu hình chạy để bạn có thể tạo Hồ sơ cơ sở riêng cho từng phiên bản.

Cấu hình chạy Tạo hồ sơ cơ sở.
Hình 2. Việc chạy cấu hình này sẽ tạo Hồ sơ cơ sở.

Khi cấu hình chạy Generate Baseline Profile (Tạo Hồ sơ cơ sở) hoàn tất, cấu hình này sẽ sao chép Hồ sơ cơ sở đã tạo vào tệp src/variant/generated/baselineProfiles/baseline-prof.txt trong mô-đun đang được lập hồ sơ. Các lựa chọn biến thể là loại bản phát hành hoặc biến thể bản dựng liên quan đến loại bản phát hành.

Hồ sơ cơ sở đã tạo vốn được tạo trong build/outputs. Đường dẫn đầy đủ sẽ được quyết định bởi biến thể hoặc phiên bản của ứng dụng đang được lập hồ sơ, cũng như việc bạn sử dụng thiết bị do Gradle quản lý hay thiết bị được kết nối để lập hồ sơ. Nếu bạn dùng tên được sử dụng trong đoạn mã còn cấu hình bản dựng do mẫu tạo, thì Hồ sơ cơ sở sẽ được tạo trong tệp build/outputs/managed_device_android_test_additional_output/nonminifiedrelease/pixel6Api31/BaselineProfileGenerator_generate-baseline-prof.txt. Có thể bạn sẽ không phải tương tác trực tiếp với phiên bản Hồ sơ cơ sở đã tạo này, trừ phi bạn sao chép theo cách thủ công vào các mô-đun đích (không nên thực hiện).

Tạo Hồ sơ cơ sở mới bằng AGP 8.1

Nếu bạn không thể sử dụng mẫu mô-đun Hồ sơ cơ sở, hãy sử dụng mẫu mô-đun Macrobenchmark và trình bổ trợ Gradle cho Hồ sơ cơ sở để tạo một Hồ sơ cơ sở mới. Bạn nên sử dụng các công cụ này trong Android Studio Giraffe và AGP 8.1 trở lên.

Dưới đây là các bước tạo Hồ sơ cơ sở mới bằng mẫu mô-đun Macrobenchmark và trình bổ trợ Gradle cho Hồ sơ cơ sở:

  1. Thiết lập mô-đun Macrobenchmark trong dự án Gradle của bạn.
  2. Xác định một lớp mới có tên là BaselineProfileGenerator:
    class BaselineProfileGenerator {
        @get:Rule
        val baselineProfileRule = BaselineProfileRule()
    
        @Test
        fun startup() = baselineProfileRule.collect(
            packageName = "com.example.app",
            profileBlock = {
                startActivityAndWait()
            }
        )
    }

    Trình tạo có thể chứa các hoạt động tương tác với ứng dụng của bạn ngoài việc khởi động ứng dụng. Nhờ đó, bạn có thể tối ưu hoá hiệu suất trong thời gian chạy của ứng dụng, chẳng hạn như việc cuộn danh sách, chạy ảnh động và di chuyển trong Activity. Hãy xem ví dụ khác về các chương trình kiểm thử sử dụng @BaselineProfileRule để cải thiện hành trình trọng yếu của người dùng.

  3. Thêm trình bổ trợ Gradle cho Hồ sơ cơ sở (libs.plugins.androidx.baselineprofile). Trình bổ trợ này giúp bạn dễ dàng tạo Hồ sơ cơ sở và duy trì các hồ sơ đó sau này.

  4. Để tạo Hồ sơ cơ sở, hãy chạy các tác vụ Gradle :app:generateBaselineProfile hoặc :app:generateVariantBaselineProfile trong thiết bị đầu cuối.

    Chạy trình tạo ở dạng kiểm thử đo lường trên thiết bị do Gradle quản lý, trình mô phỏng hoặc thiết bị thực đã bị can thiệp vào hệ thống. Nếu bạn sử dụng một Thiết bị do Gradle quản lý, hãy thiết lập aosp thành systemImageSource, vì bạn cần có quyền truy cập thư mục gốc cho trình tạo Hồ sơ cơ sở.

    Khi bạn kết thúc tác vụ tạo, Hồ sơ cơ sở sẽ được sao chép vào app/src/variant/generated/baselineProfiles.

Tạo Hồ sơ cơ sở mới mà không cần mẫu

Bạn nên tạo Hồ sơ cơ sở bằng mẫu mô-đun Hồ sơ cơ sở của Android Studio (ưu tiên) hoặc mẫu Macrobenchmark, nhưng bạn cũng có thể sử dụng riêng Trình bổ trợ Gradle cho Hồ sơ cơ sở. Để đọc thêm về trình bổ trợ Gradle cho Hồ sơ cơ sở, hãy xem bài viết Thiết lập quy trình tạo Hồ sơ cơ sở.

Sau đây là cách tạo Hồ sơ cơ sở trực tiếp bằng trình bổ trợ Gradle cho Hồ sơ cơ sở:

  1. Tạo một mô-đun com.android.test mới – ví dụ: :baseline-profile.
  2. Định cấu hình tệp build.gradle.kts cho :baseline-profile:

    1. Áp dụng trình bổ trợ androidx.baselineprofile.
    2. Đảm bảo targetProjectPath trỏ đến mô-đun :app.
    3. Thêm thiết bị do Gradle quản lý (GMD) (không bắt buộc). Trong ví dụ sau đây, đó là pixel6Api31. Nếu không được chỉ định, trình bổ trợ sẽ sử dụng một thiết bị được kết nối, đó là thiết bị mô phỏng hoặc thiết bị thực.
    4. Áp dụng cấu hình bạn muốn, như trong ví dụ sau.

    Kotlin

    plugins {
        id("com.android.test")
        id("androidx.baselineprofile")
    }
    
    android {
        defaultConfig {
            ...
        }
    
        // Point to the app module, the module that you're generating the Baseline Profile for.
        targetProjectPath = ":app"
        // Configure a GMD (optional).
        testOptions.managedDevices.devices {
            pixel6Api31(com.android.build.api.dsl.ManagedVirtualDevice) {
                device = "Pixel 6"
                apiLevel = 31
                systemImageSource = "aosp"
            }
        }
    }
    
    dependencies { ... }
    
    // Baseline Profile Gradle plugin configuration. Everything is optional. This
    // example uses the GMD added earlier and disables connected devices.
    baselineProfile {
        // Specifies the GMDs to run the tests on. The default is none.
        managedDevices += "pixel6Api31"
        // Enables using connected devices to generate profiles. The default is
        // `true`. When using connected devices, they must be rooted or API 33 and
        // higher.
        useConnectedDevices = false
    }

    Groovy

    plugins {
        id 'com.android.test'
        id 'androidx.baselineprofile'
    }
    
    android {
        defaultConfig {
            ...
        }
    
        // Point to the app module, the module that you're generating the Baseline Profile for.
        targetProjectPath ':app'
        // Configure a GMD (optional).
        testOptions.managedDevices.devices {
            pixel6Api31(com.android.build.api.dsl.ManagedVirtualDevice) {
                device 'Pixel 6'
                apiLevel 31
                systemImageSource 'aosp'
            }
        }
    }
    
    dependencies { ... }
    
    // Baseline Profile Gradle plugin configuration. Everything is optional. This
    // example uses the GMD added earlier and disables connected devices.
    baselineProfile {
        // Specifies the GMDs to run the tests on. The default is none.
        managedDevices ['pixel6Api31']
        // Enables using connected devices to generate profiles. The default is
        // `true`. When using connected devices, they must be rooted or API 33 and
        // higher.
        useConnectedDevices false
    }
  3. Tạo một bài kiểm thử Hồ sơ cơ sở trong mô-đun kiểm thử :baseline-profile. Sau đây là ví dụ về một bài kiểm thử khởi động ứng dụng và chờ cho ứng dụng ở trạng thái rảnh.

    Kotlin

    class BaselineProfileGenerator {
    
        @get:Rule
        val baselineRule = BaselineProfileRule()
    
        @Test
        fun startupBaselineProfile() {
            baselineRule.collect("com.myapp") {
                startActivityAndWait()
            }
        }
    }

    Java

    public class BaselineProfileGenerator {
    
        @Rule
        Public BaselineProfileRule baselineRule = new BaselineProfileRule();
    
        @Test
        Public void startupBaselineProfile() {
            baselineRule.collect(
                "com.myapp",
                (scope -> {
                    scope.startActivityAndWait();
                    Return Unit.INSTANCE;
                })
            )
        }
    }
  4. Cập nhật tệp build.gradle.kts trong mô-đun ứng dụng, ví dụ: :app.

    1. Áp dụng trình bổ trợ androidx.baselineprofile.
    2. Thêm một phần phụ thuộc baselineProfile vào mô-đun :baseline-profile.

    Kotlin

    plugins {
        id("com.android.application")
        id("androidx.baselineprofile")
    }
    
    android {
        // There are no changes to the `android` block.
        ...
    }
    
    dependencies {
        ...
        // Add a `baselineProfile` dependency on the `:baseline-profile` module.
        baselineProfile(project(":baseline-profile"))
    }

    Groovy

    plugins {
        id 'com.android.application'
        id 'androidx.baselineprofile'
    }
    
    android {
        // No changes to the `android` block.
        ...
    }
    
    dependencies {
        ...
        // Add a `baselineProfile` dependency on the `:baseline-profile` module.
        baselineProfile ':baseline-profile'
    }
  5. Tạo hồ sơ bằng cách chạy các tác vụ Gradle :app:generateBaselineProfile hoặc :app:generateVariantBaselineProfile.

  6. Khi bạn kết thúc tác vụ tạo, Hồ sơ cơ sở sẽ được sao chép vào app/src/variant/generated/baselineProfiles.

Tạo Hồ sơ cơ sở mới bằng AGP 7.3-7.4

Bạn có thể tạo Hồ sơ cơ sở bằng AGP 7.3-7.4, nhưng bạn nên nâng cấp lên tối thiểu là AGP 8.1 để có thể sử dụng trình bổ trợ Gradle cho Hồ sơ cơ sở cũng như các tính năng mới nhất của trình bổ trợ này.

Nếu bạn cần tạo Hồ sơ cơ sở bằng AGP 7.3-7.4, các bước này sẽ giống như các bước dành cho AGP 8.1, nhưng sẽ có những ngoại lệ sau:

Áp dụng theo cách thủ công các quy tắc đã tạo

Trình tạo Hồ sơ cơ sở sẽ tạo một tệp văn bản có Định dạng mà con người có thể đọc được (HRF) trên thiết bị rồi sao chép tệp đó vào máy chủ lưu trữ. Để áp dụng hồ sơ đã tạo cho mã của bạn, hãy làm theo các bước sau:

  1. Tìm tệp HRF trong thư mục bản dựng của mô-đun mà bạn tạo hồ sơ: [module]/build/outputs/managed_device_android_test_additional_output/[device].

    Các hồ sơ tuân theo mẫu đặt tên [class name]-[test method name]-baseline-prof.txt, có dạng như sau: BaselineProfileGenerator-startup-baseline-prof.txt.

  2. Sao chép hồ sơ đã tạo vào src/main/ rồi đổi tên tệp đó thành baseline-prof.txt.

  3. Thêm phần phụ thuộc vào thư viện ProfileInstaller trong tệp build.gradle.kts của ứng dụng để bật tính năng biên dịch Hồ sơ cơ sở cục bộ khi chưa có Hồ sơ trên đám mây. Đây là cách duy nhất để cài đặt một Hồ sơ cơ sở ở phạm vi cục bộ mà không qua cửa hàng ứng dụng.

    dependencies {
         implementation("androidx.profileinstaller:profileinstaller:1.4.1")
    }
    
  4. Xây dựng phiên bản phát hành chính thức của ứng dụng, trong khi các quy tắc HRF áp dụng được biên dịch thành dạng nhị phân và đưa vào APK hoặc AAB. Sau đó, phân phối ứng dụng như bình thường.

Đo điểm chuẩn cho Hồ sơ cơ sở

Để đo điểm chuẩn cho Hồ sơ cơ sở của bạn, hãy tạo một cấu hình mới để chạy kiểm thử đo lường Android thông qua thao tác định hướng (gutter action) mà sẽ thực thi phép đo điểm chuẩn được xác định trong StartupBenchmarks.kt hoặc StartupBencharks.java. Để tìm hiểu thêm về kiểm thử điểm chuẩn, hãy xem phần Tạo lớp MacrobenchmarkTự động đo lường bằng thư viện Macrobenchmark.

Hình 3. Chạy chương trình kiểm thử Android thông qua thao tác định hướng.

Khi bạn chạy chương trình này trong Android Studio, dữ liệu đầu ra của bản dựng sẽ chứa thông tin về các điểm cải thiện tốc độ mà Hồ sơ cơ sở cung cấp:

StartupBenchmarks_startupCompilationBaselineProfiles
timeToInitialDisplayMs   min 161.8,   median 178.9,   max 194.6
StartupBenchmarks_startupCompilationNone
timeToInitialDisplayMs   min 184.7,   median 196.9,   max 202.9

Ghi lại mọi đường dẫn mã bắt buộc

Sau đây là 2 chỉ số chính giúp đo lường thời gian khởi động ứng dụng:

Thời gian hiển thị khung hình đầu tiên (TTID)
Thời gian cần thiết để hiển thị khung hình đầu tiên trên giao diện người dùng của ứng dụng.
Thời gian hiển thị đầy đủ (TTFD)
TTID cộng với thời gian hiển thị nội dung tải không đồng bộ sau khi hiển thị khung hình đầu tiên.

TTFD được báo cáo sau khi phương thức reportFullyDrawn() của ComponentActivity được gọi. Nếu reportFullyDrawn() không được gọi, thì TTID sẽ được báo cáo. Có thể bạn cần phải trì hoãn thời điểm reportFullyDrawn() được gọi cho đến khi quá trình tải không đồng bộ hoàn tất. Ví dụ: nếu giao diện người dùng chứa một danh sách động, chẳng hạn như danh sách RecyclerView hoặc danh sách từng phần, thì có thể danh sách này sẽ được điền bằng một tác vụ trong nền (hoàn tất sau khi danh sách này hiển thị lần đầu và do đó, chính là thời điểm sau khi giao diện người dùng được đánh dấu là đã hiển thị đầy đủ). Trong những trường hợp như vậy, đoạn mã chạy sau khi giao diện người dùng đạt trạng thái hiển thị đầy đủ sẽ không được đưa vào Hồ sơ cơ sở.

Để đưa hoạt động điền danh sách vào Hồ sơ cơ sở, hãy lấy FullyDrawnReporter bằng cách sử dụng getFullyDrawnReporter() và thêm một trình báo cáo vào đó trong mã lập trình ứng dụng của bạn. Giải phóng trình báo cáo khi tác vụ trong nền điền xong danh sách. FullyDrawnReporter không gọi phương thức reportFullyDrawn() cho đến khi mọi trình báo cáo được giải phóng. Bằng cách này, Hồ sơ cơ sở sẽ bao gồm các đường dẫn mã cần thiết để điền danh sách. Điều này không làm thay đổi hành vi của ứng dụng đối với người dùng nhưng cho phép đưa mọi đường dẫn mã cần thiết vào Hồ sơ cơ sở.

Nếu ứng dụng của bạn dùng Jetpack Compose, hãy sử dụng các API sau để biểu thị trạng thái hiển thị đầy đủ:

  • ReportDrawn cho biết thành phần kết hợp của bạn đã sẵn sàng tương tác ngay lập tức.
  • ReportDrawnWhen sử dụng một thuộc tính, chẳng hạn như list.count > 0, để cho biết thời điểm thành phần kết hợp của bạn đã sẵn sàng tương tác.
  • ReportDrawnAfter sử dụng một phương thức tạm ngưng mà khi phương thức này hoàn tất, sẽ cho biết thành phần kết hợp của bạn đã sẵn sàng tương tác.