{"id":19607070,"url":"https://github.com/bookingcom/perfsuite-android","last_synced_at":"2025-04-27T19:33:07.483Z","repository":{"id":185629466,"uuid":"639945082","full_name":"bookingcom/perfsuite-android","owner":"bookingcom","description":"Lightweight Android library for collecting basic app performance metrics","archived":false,"fork":false,"pushed_at":"2024-04-24T11:03:46.000Z","size":145,"stargazers_count":114,"open_issues_count":3,"forks_count":9,"subscribers_count":11,"default_branch":"main","last_synced_at":"2025-04-05T03:02:04.261Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bookingcom.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2023-05-12T15:30:35.000Z","updated_at":"2025-03-24T09:18:38.000Z","dependencies_parsed_at":null,"dependency_job_id":"88b51412-4ded-4062-9bca-af13a4a6c770","html_url":"https://github.com/bookingcom/perfsuite-android","commit_stats":null,"previous_names":["bookingcom/perfsuite-android"],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bookingcom%2Fperfsuite-android","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bookingcom%2Fperfsuite-android/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bookingcom%2Fperfsuite-android/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bookingcom%2Fperfsuite-android/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bookingcom","download_url":"https://codeload.github.com/bookingcom/perfsuite-android/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251196446,"owners_count":21550953,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-11T10:08:43.854Z","updated_at":"2025-04-27T19:33:07.177Z","avatar_url":"https://github.com/bookingcom.png","language":"Kotlin","funding_links":[],"categories":["🔥 最近收录"],"sub_categories":[],"readme":"# PerformanceSuite Android\n\n[![CI status](https://github.com/bookingcom/perfsuite-android/actions/workflows/ci.yml/badge.svg)](https://github.com/bookingcom/perfsuite-android/actions/workflows/ci.yml)\n[![License](https://img.shields.io/badge/License-Apache_2.0-green.svg)](https://github.com/bookingcom/perfsuite-android/blob/main/LICENSE)\n[![Release version](https://img.shields.io/github/release/bookingcom/perfsuite-android.svg?label=Release)](https://github.com/bookingcom/perfsuite-android/releases)\n\nLightweight library designed to measure and collect performance metrics for Android applications \nin production.\n\nUnlike other SaaS solutions (like Firebase Performance) it focuses only on collecting pure metrics \nand not enforces you to use specific reporting channel and monitoring infrastructure, so you're \nflexible with re-using the monitoring approaches already existing in your product.\n\n## Getting started\n\nLibrary supports collecting following performance metrics:\n- App Cold Startup Time\n- Rendering performance per Activity\n- Time to Interactive \u0026 Time to First Render per screen\n\nWe recommend to read our blogpost [\"Measuring mobile apps performance in production\"](https://medium.com/booking-com-development/measuring-mobile-apps-performance-in-production-726e7e84072f) \nfirst to get some idea on what are these performance metrics, how they work and why those were chosen.\n\n\u003e NOTE: You can also refer to the [SampleApp](sampleApp/src/main/java/com/booking/perfsuite/app) \n\u003e in this repo to see a simplified example of how the library can be used in the real app\n\n### Dependency\n\nThe library is available on Maven Central:\n```groovy\nimplementation(\"com.booking:perfsuite:0.3\")\n```\n\n### Collecting Startup Times\n\nImplement the callback invoked once [Startup Time](https://medium.com/booking-com-development/measuring-mobile-apps-performance-in-production-726e7e84072f#e383) is collected:\n\n```kotlin\nclass MyStartupTimeListener : AppStartupTimeTracker.Listener {\n\n    override fun onColdStartupTimeIsReady(\n        startupTime: Long,\n        firstActivity: Activity,\n        isActualColdStart: Boolean\n    ) {\n        // Log or report Startup Time metric in a preferable way\n    }\n}\n```\n\nThen register your listener as early in `Application#onCreate` as possible:\n\n```kotlin\nclass MyApplication : Application() {\n\n    override fun onCreate() {\n        super.onCreate()\n        AppStartupTimeTracker.register(this, MyStartupTimeListener())\n    }\n}\n```\n\n### Collecting Frame Metrics\n\nImplement the callback invoked every time when the foreground `Activity` is paused \n(we can call it \"the end of the screen session\") and use `RenderingMetricsMapper` to\nrepresent [rendering performance metrics](https://medium.com/booking-com-development/measuring-mobile-apps-performance-in-production-726e7e84072f#3eca) \nin a convenient aggregated format:\n\n```kotlin\nclass MyFrameMetricsListener : ActivityFrameMetricsTracker.Listener {\n\n    override fun onFramesMetricsReady(\n        activity: Activity,\n        frameMetrics: Array\u003cSparseIntArray\u003e,\n        foregroundTime: Long?\n    ) {\n        val data = RenderingMetricsMapper.toRenderingMetrics(frameMetrics, foregroundTime) ?: return\n        // Log or report Frame Metrics for current Activity's \"session\" in a preferable way\n    }\n}\n```\n\nThen register your listener in `Application#onCreate` before any activity is created:\n\n```kotlin\nclass MyApplication : Application() {\n\n    override fun onCreate() {\n        super.onCreate()\n        ActivityFrameMetricsTracker.register(this, MyFrameMetricsListener)\n    }\n}\n```\n\nAs per the code sample above you can use `RenderingMetricsMapper` to collect frames metics in the aggreated format which is convenient for reporting to the backend.\nThen metrics will be represented as [`RenderingMetrics`](src/main/java/com/booking/perfsuite/rendering/RenderingMetrics.kt) instance, which will provide data on:\n- `totalFrames` - total amount of frames rendered during the screen session\n- `totalFreezeTimeMs` - total accumulated time of the UI being frozen during the screen session\n- `slowFrames` - amount of [slow frames](https://firebase.google.com/docs/perf-mon/screen-traces?platform=android#slow-rendering-frames) per screens session\n- `frozenFrames` - amount of [frozen frames](https://firebase.google.com/docs/perf-mon/screen-traces?platform=android#frozen-frames) per screens session\n\nEven though we support collecting widely used slow \u0026 frozen frames we [strongly recommend relying on `totalFreezeTimeMs` as the main rendering metric](https://medium.com/booking-com-development/measuring-mobile-apps-performance-in-production-726e7e84072f#2d5d)\n\n### Collecting Screen Time to Interactive (TTI)\n\nImplement the callbacks invoked every time when screen's\n[Time To Interactive (TTI)](https://medium.com/booking-com-development/measuring-mobile-apps-performance-in-production-726e7e84072f#ad4d) \u0026\n[Time To First Render (TTFR)](https://medium.com/booking-com-development/measuring-mobile-apps-performance-in-production-726e7e84072f#f862)\nmetrics are collected:\n\n```kotlin\nobject MyTtiListener : BaseTtiTracker.Listener {\n\n    override fun onScreenCreated(screen: String) {}\n\n    override fun onFirstFrameIsDrawn(screen: String, duration: Long) {\n        // Log or report TTFR metrics for specific screen in a preferable way\n    }\n    override fun onFirstUsableFrameIsDrawn(screen: String, duration: Long) {\n        // Log or report TTI metrics for specific screen in a preferable way\n    }\n}\n```\n\nThen instantiate TTI tracker in `Application#onCreate` before any activity is created and using this listener:\n\n```kotlin\n// keep instances globally accessible or inject as singletons using any preferable DI framework\nval ttiTracker = BaseTtiTracker(AppTtiListener)\nval viewTtiTracker = ViewTtiTracker(ttiTracker)\n\nclass MyApplication : Application() {\n\n    override fun onCreate() {\n        super.onCreate()\n        ActivityTtfrHelper.register(this, viewTtiTracker)\n    }\n}\n```\n\nThat will enable automatic TTFR collection for every Activity in the app.\nFor TTI collection you'll need to call `viewTtiTracker.onScreenIsUsable(..)` manually from the Activity, \nwhen the meaningful data is visible to the user e.g.:\n\n```kotlin\n// call this e.g. when the data is received from the backend,\n// progress bar stops spinning and screen is fully ready for the user\nviewTtiTracker.onScreenIsUsable(activity.componentName, rootContentView)\n```\n\nSee the [SampleApp](sampleApp/src/main/java/com/booking/perfsuite/app) for a full working example\n\n#### Collecting TTI/TTFR for `Fragment`-based screens in single-Activity apps\n\nThe example above works for `Activity`-based screens, however if you use the \"Single-Activity\" approach you also need\nto enable TTI/TTFR tracking for the Fragments inside you main Activity:\n\n```kotlin\nclass MyMainActivity : Activity() {\n\n    override fun onCreate() {\n        super.onCreate()\n        val fragmentHelper = FragmentTtfrHelper(viewTtiTracker)\n        supportFragmentManager.registerFragmentLifecycleCallbacks(fragmentHelper, true)\n    }\n}\n```\nThen you can call `viewTtiTracker.onScreenIsUsable(..)` in Fragments the same way as described above. \n\n## Additional documentation\n- [Measuring mobile apps performance in production](https://medium.com/booking-com-development/measuring-mobile-apps-performance-in-production-726e7e84072f) \n- [App Startup Time documentation by Google](https://developer.android.com/topic/performance/vitals/launch-time)\n- [Rendering Performance documentation by Google](https://developer.android.com/topic/performance/vitals/render)\n- [Android Vitals Articles by Pierre Yves Ricau](https://dev.to/pyricau/series/7827)\n  \n## ACKNOWLEDGMENT\n\nThis software was originally developed at Booking.com. \nWith approval from Booking.com, this software was released as open source, \nfor which the authors would like to express their gratitude.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbookingcom%2Fperfsuite-android","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbookingcom%2Fperfsuite-android","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbookingcom%2Fperfsuite-android/lists"}