Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
JankStats LibraryでJankを検出しよう / Detecting Jank w...
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
KeitaTakahashi
July 11, 2023
Technology
1.9k
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
JankStats LibraryでJankを検出しよう / Detecting Jank with JankStats Library
KeitaTakahashi
July 11, 2023
More Decks by KeitaTakahashi
See All by KeitaTakahashi
誰と働くか / Who I work with
tkhskt
1
190
ZOZOTOWN AndroidへのJetpack Composeの導入 / Introducing Jetpack Compose for ZOZOTOWN Android
tkhskt
1
12k
Other Decks in Technology
See All in Technology
「最後に責任を取るのはチーム」— 人間のPRレビューを最小化してアップデートしたメンタルモデル
jnishime_dresscode
0
580
世界、断片、モデル。そして理解
ardbeg1958
1
110
AI Agent SaaS を支える自社仮想化基盤への挑戦と実運用 / ai-agent-saas-virtualization
flatt_security
2
3.8k
10年目を迎えた「ABEMA」がどのように AI 活用を推進して、AI 駆動開発にシフトしているのか / How ABEMA, entering its 10th year, is promoting the use of AI and shifting toward AI-driven development
miyukki
0
130
凡エンジニアがこの先生きのこるためには。〜TypeScript完全に理解したい〜
alchemy1115
2
170
しくみを学んで使いこなそう GitHub Copilot app
torumakabe
2
230
タスクの複雑さでモデルを選ぶ ── Thompson Samplingで動かす“トークン/コスト最適化
satohy0323
0
310
Gen3R: 3D Scene Generation Meets Feed-Forward Reconstruction
spatial_ai_network
0
120
Oracle Base Database Service 技術詳細
oracle4engineer
PRO
15
110k
ローカルLLMとLINE Botの組み合わせ その3 / LINE DC Generative AI Meetup #8
you
PRO
0
130
Claude Code公式skillで 自分の仕事を少しずつ手放そう!(Claude Code開発ノウハウ大公開スペシャル by クラスメソッド)
kaym
1
290
インフラと開発の垣根を超えていき!〜元AWSインフラエンジニアがAWS開発で奮闘している話〜
hatahata021
1
170
Featured
See All Featured
Rebuilding a faster, lazier Slack
samanthasiow
85
9.6k
The agentic SEO stack - context over prompts
schlessera
0
840
Paper Plane (Part 1)
katiecoart
PRO
0
9.6k
Navigating the Design Leadership Dip - Product Design Week Design Leaders+ Conference 2024
apolaine
1
370
Fantastic passwords and where to find them - at NoRuKo
philnash
52
3.8k
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
659
62k
Between Models and Reality
mayunak
4
370
Ethics towards AI in product and experience design
skipperchong
2
330
We Have a Design System, Now What?
morganepeng
55
8.2k
Navigating Algorithm Shifts & AI Overviews - #SMXNext
aleyda
1
1.4k
エンジニアに許された特別な時間の終わり
watany
107
250k
The Language of Interfaces
destraynor
162
27k
Transcript
JankStats LibraryでJankを 検出しよう 2023/07/11 ZOZO Tech Meetup - iOS/Android 株式会社ZOZO
ZOZOTOWN開発本部 ZOZOTOWNアプリ部 Android2ブロック Androidテックリード 高橋啓太 Copyright © ZOZO, Inc. 1
© ZOZO, Inc. 2 株式会社ZOZO ZOZOTOWN開発本部 ZOZOTOWNアプリ部 Android2ブ ロック Androidテックリード
高橋 啓太 2020年新卒入社
© ZOZO, Inc. 話すこと 3 • JankStats Libraryの基本的な情報 • Jankとは
• Jank検出ツール • JankStats Libraryの基本的な使用方法
© ZOZO, Inc. JankStats Libraryの基本的な情報 4 • アプリのレンダリングパフォーマンスに関する情報を取得することができる ◦ 後述する「Jank」を検出可能
• FrameMetrics APIやOnPreDrawListenerの上に構築されている • 2023/07/11時点ではApril 5, 2023リリースの1.0.0-alpha04が最新 • android/nowinandroidにも入っている Metrics | Jetpack | Android Developers: https://developer.android.com/jetpack/androidx/releases/metrics android/nowinandroid | GitHub: https://github.com/android/nowinandroid
© ZOZO, Inc. 5 Jankとは
© ZOZO, Inc. Jankとは 6 遅いレンダリング | App quality |
Android Developers: https://developer.android.com/topic/performance/vitals/render?hl=ja • ユーザーがスムーズにアプリを操作するためには、各デバイスで決められたリフ レッシュレートを達成できるようフレーム生成時間を維持することが必要 ◦ 一般的には60fpsを達成することが必要 • なんらかの理由でフレームがスキップされ、アプリの動作がスムーズでなくなるこ とを「Jank(ジャンク)」と呼ぶ
© ZOZO, Inc. Jankとは - ANR等との関係性 7 ジャンクのトラッキング | App
quality | Android Developers: https://developer.android.com/topic/performance/vitals/tracking_jank?hl=ja 遅いフレーム フリーズしたフレーム ANR 表示に要する時間 16ms~700ms 700ms~5s 5sより長い ユーザーが知覚できる現象の例 リストのスクロールがカクつく 画面遷移時がスムーズではない 画面をタップしても5秒以上反応がな い
© ZOZO, Inc. Jankとは - ANR等との関係性 8 → これらは全てJankに分類される 遅いフレーム
フリーズしたフレーム ANR 表示に要する時間 16ms~700ms 700ms~5s 5sより長い ユーザーが知覚できる現象の例 リストのスクロールがカクつく 画面遷移時がスムーズではない 画面をタップしても5秒以上反応がな い ジャンクのトラッキング | App quality | Android Developers: https://developer.android.com/topic/performance/vitals/tracking_jank?hl=ja
© ZOZO, Inc. Jankとは - ANR等との関係性 9 → これらは全てJankに分類される →
Jankの検出・修正は、快適な操作感を維持するために重要 遅いフレーム フリーズしたフレーム ANR 表示に要する時間 16ms~700ms 700ms~5s 5sより長い ユーザーが知覚できる現象の例 リストのスクロールがカクつく 画面遷移時がスムーズではない 画面をタップしても5秒以上反応がな い ジャンクのトラッキング | App quality | Android Developers: https://developer.android.com/topic/performance/vitals/tracking_jank?hl=ja
© ZOZO, Inc. 10 Jank検出ツール
© ZOZO, Inc. Perfetto 11 • ADBを介して、Android端末からフレームの情報を含むパフォーマンス情報を取得 するツール • 取得したパフォーマンス情報はPerfetto
UIで可視化して分析可能 • ZOZOTOWNではスクロール時のJankを分析する際に使用した Perfetto: https://perfetto.dev/ perfetto | Android Developers: https://developer.android.com/studio/command-line/perfetto?hl=ja Perfettoを用いたAndroidアプリのボトルネックの特定とその改善 | ZOZO TECH BLOG: https://techblog.zozo.com/entry/android-performance-improvement-with-perfetto
© ZOZO, Inc. AndroidStudio Profiler 12 • Chipmunk以降のAndroid StudioではProfilerでJankを検出可能 ◦
Android12以降の端末が必要 Android Developers Japan Blog: Android Studio の CPU profiler で UI のジャンクを検出する https://android-developers-jp.googleblog.com/2022/07/spot-your-ui-jank-using-cpu-profiler-in-android-studio.html
© ZOZO, Inc. JankStats Library 13 • androidx.metrics.performance • 下記の機能を提供する
◦ Jankの識別 ▪ Jankの発生タイミングに関する情報を取得できる ◦ Jankが発生した時点でのアプリの状態取得 ▪ Jankが発生した際にユーザーがどのような操作をしていたかを確認できる ◦ 結果のレポート ▪ フレームに関する情報(完了にかかった時間など)を取得できる
© ZOZO, Inc. JankStats Libraryの何が良いのか? 14 • 開発環境でのJank検出はPerfettoやAndroid StudioのProfilerで十分可能 •
しかし、本番環境(ユーザーの手元)で実際に発生しているJankを検出することは できない • JankStats Libraryをプロダクトに導入し、データを収集することで、本番環境で発 生しているJankの原因が分析可能になる ◦ 取得したデータの保存やデータを送信する仕組みは提供されていない ※「保存とアップロードに関する詳細情報は、JankStats API アルファ版リリースでは提供されません」 とあるので将来的になんらかのサポートが追加される可能性はある https://developer.android.com/topic/performance/jankstats?hl=ja
© ZOZO, Inc. 15 JankStats Libraryの基本的な使用方法
© ZOZO, Inc. 16 JankStats Libraryの基本的な使用方法 ※alpha版のため今後APIが変更される場合があります
© ZOZO, Inc. 導入 17 implementation "androidx.metrics:metrics-performance:1.0.0-alpha04" 何はともあれimplementation
© ZOZO, Inc. class MainActivity : ComponentActivity() { private lateinit
var jankStats: JankStats override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { ... } jankStats = JankStats.createAndTrack(window) { frameData -> if (frameData.isJank) { // Jankと判定されたフレームかどうか Log.v("Jank detected!", frameData.toString()) } } } } 基本的な使用方法 - 初期化 18 JankStats.createAndTrackでJankStatsのインスタンスを生成
© ZOZO, Inc. class MainActivity : ComponentActivity() { private lateinit
var jankStats: JankStats override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { ... } jankStats = JankStats.createAndTrack(window) { frameData -> if (frameData.isJank) { // Jankと判定されたフレームかどうか Log.v("Jank detected!", frameData.toString()) } } } } 基本的な使用方法 - 初期化 JankStats.createAndTrackでJankStatsのインスタンスを生成 19 JankStatsのインスタンス生成時にdecorViewが生成されていない場合、 IllegalStateExceptionが発生するので注意
© ZOZO, Inc. 基本的な使用方法 - 初期化 20 class MainActivity
: ComponentActivity() { private lateinit var jankStats: JankStats override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { ... } jankStats = JankStats.createAndTrack(window) { frameData -> if (frameData.isJank) { // Jankと判定されたフレームかどうか Log.v("Jank detected!", frameData.toString()) } } } } JankStats.createAndTrackの第二引数には、フレーム情報を受け取るコールバック (JankStats.OnFrameListener)を渡す
© ZOZO, Inc. 21 isTrackingEnabledでフレーム情報収集の有効/無効を切り替える(デフォルト値はtrue) class MainActivity : ComponentActivity() {
... override fun onResume() { super.onResume() ... jankStats.isTrackingEnabled = true } override fun onPause() { super.onPause() jankStats.isTrackingEnabled = false } } 基本的な使用方法 - 初期化
© ZOZO, Inc. 基本的な使用方法 - FrameData 22 FrameData(フレームの情報)がLogcatに出力される
© ZOZO, Inc. 基本的な使用方法 - FrameData 23 • frameStartNanos ◦
フレームの開始時刻(ns) • frameDurationUiNanos ◦ フレームの長さ(ns) • isJank ◦ ジャンクかどうかを示すフラグ • states ◦ アプリの状態 (StateInfo) JankStats ライブラリ | App quality | Android Developers: https://developer.android.com/topic/performance/jankstats?hl=ja#reporting
© ZOZO, Inc. 基本的な使用方法 - FrameData 24 • frameStartNanos ◦
フレームの開始時刻(ns) • frameDurationUiNanos ◦ フレームの長さ(ns) • isJank ◦ ジャンクかどうかを示すフラグ • states ◦ アプリの状態 (StateInfo) JankStats ライブラリ | App quality | Android Developers: https://developer.android.com/topic/performance/jankstats?hl=ja#reporting
© ZOZO, Inc. 基本的な使用方法 - FrameData 25
© ZOZO, Inc. 基本的な使用方法 - FrameData 26 空だが...?
© ZOZO, Inc. @Composable fun rememberMetricsStateHolder(): PerformanceMetricsState.Holder { val view
= LocalView.current return remember(view) { PerformanceMetricsState.getHolderForHierarchy(view) } } 基本的な使用方法 - PerformanceMetricsState 27 PerformanceMetricsState.Holderを使用する
© ZOZO, Inc. 基本的な使用方法 - PerformanceMetricsState 28 @Composable fun JankyScreen()
{ val holder = rememberMetricsStateHolder() val key = "画面名" LaunchedEffect(holder) { // 状態を設定 holder.state?.putState(key, "JankyScreen") } JankyLazyColumn() // Jankが発生するComposable } PerformanceMetricsState#putStateにkey-value形式で状態をアプリの設定する
© ZOZO, Inc. 基本的な使用方法 - PerformanceMetricsState 29
© ZOZO, Inc. 基本的な使用方法 - PerformanceMetricsState 30 フレーム情報と アプリの状態が対応する🎉
© ZOZO, Inc. 基本的な使用方法 - PerformanceMetricsState 31 @Composable fun JankyScreen()
{ ... Column { Button(onClick = { // 無効になった状態を削除 holder.state?.removeState(key) }) { Text(text = "状態削除") } JankyLazyColumn() } }
© ZOZO, Inc. 基本的な使用方法 - PerformanceMetricsState 32 ボタンを押す前 ボタンを押した後 状態の削除も明示的に行う必要がある
© ZOZO, Inc. 基本的な使用方法 - nowinandroidの場合 33 nowinandroidではJankStatsを使用したJank検出用のComposableを作成し、 画面遷移時とスクロール時にputState/removeStateを実行している
© ZOZO, Inc. 基本的な使用方法 - nowinandroidの場合 34 nowinandroid | NiaAppState.kt:
https://github.com/android/nowinandroid/blob/main/app/src/main/java/com/google/samples/apps/nowinandroid/ui/NiaAppState.kt @Composable private fun NavigationTrackingSideEffect(navController: NavHostController) { TrackDisposableJank(navController) { metricsHolder -> val listener = NavController.OnDestinationChangedListener { _, destination, _ -> metricsHolder.state?.putState("Navigation", destination.route.toString()) } navController.addOnDestinationChangedListener(listener) onDispose { navController.removeOnDestinationChangedListener(listener) } } }
© ZOZO, Inc. 基本的な使用方法 - nowinandroidの場合 35 nowinandroid | JankStatsExtensions.kt:
https://github.com/android/nowinandroid/blob/4d65946f95f55505a21a1651c2fd5587cd5bb533/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/JankStatsExtensions.kt @Composable fun TrackScrollJank(scrollableState: ScrollableState, stateName: String) { TrackJank(scrollableState) { metricsHolder -> snapshotFlow { scrollableState.isScrollInProgress }.collect { isScrollInProgress -> metricsHolder.state?.apply { if (isScrollInProgress) { putState(stateName, "Scrolling=true") } else { removeState(stateName) } } } } }
© ZOZO, Inc. JankStats Libraryの使用方法まとめ 36 • フレーム情報の収集はコールバックを登録するだけなのでお手軽 • フレームの情報とアプリの状態を紐づけるには
PerformanceMetricsState#putStateを使用する • 無効になったアプリの状態はremoveStateで削除する • 状態管理にはDisposableEffectやLifecycleObserverを活用するのが良さそう ※ putSingleFrameStateという1フレーム分の状態を登録し、自動で削除するAPIもあります(使い所が難しい) ※
© ZOZO, Inc. 37 まとめと感想
© ZOZO, Inc. まとめと感想 38 • Jankとはフレームがスキップされ、アプリがスムーズでなくなることを指す • JankStats Libraryは本番環境で使用することで価値を発揮する
◦ ユーザーの手元で発生しているJankが検出可能になる ◦ Jankの分析に有用なデータを収集するためには、アプリのどのような情報をフ レームの情報に乗せるかが重要になりそう
None