Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
JankStats LibraryでJankを検出しよう / Detecting Jank w...
Search
KeitaTakahashi
July 11, 2023
Technology
2k
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
FactoryBotアンチパターン / factory_bot anti-patterns
toshimaru
0
130
OpenSharing について熱く語る〜AI アセットの共有について〜
kameitomohiro
0
230
個別開発で終わらせない。 現場の課題をプロダクトの強さに変える StockmarkのFDE
ktkrhr
0
590
[2026 Oracle Technical Deep Dive] Apache Iceberg × Oracle AI Database -Oracle Autonomous AI Lakehouseが実現するAI時代のデータ基盤- (2026年9月17日開催)
oracle4engineer
PRO
0
110
Execution in the Kingdom of Agents: Reflections on Abstraction and Complexity
bcantrill
0
840
自律型 AI をセキュアに実装!Gemini と MIG で作る動的コード実行環境
recruitengineers
PRO
1
210
私の推しは「聞いてから進む」AIです -AI-DLCに一人でアプリを作らせた話
yama3133
1
170
More Freedom on the Same Shared GPU Cluster: A Small Team’s Experience with vCluster
nttcom
0
130
Google Cloud Next Tokyo 26登壇時のスクリプト
recruitengineers
PRO
0
190
freeeらしさをAIとともに作る / Creating the freee Experience with AI
ymrl
0
200
カンファレンスに参加した後の浮遊感とセルフケア
pauli
0
310
「とりあえず動く」の先へ。 AI時代のチーム開発と内部設計/2026-slsdays
slsops
0
150
Featured
See All Featured
Unsuck your backbone
ammeep
672
58k
Test your architecture with Archunit
thirion
2
2.4k
The agentic SEO stack - context over prompts
schlessera
0
960
Effective software design: The role of men in debugging patriarchy in IT @ Voxxed Days AMS
baasie
1
550
Fashionably flexible responsive web design (full day workshop)
malarkey
409
67k
The AI Revolution Will Not Be Monopolized: How open-source beats economies of scale, even for LLMs
inesmontani
PRO
3
3.8k
Connecting the Dots Between Site Speed, User Experience & Your Business [WebExpo 2025]
tammyeverts
11
1k
We Are The Robots
honzajavorek
0
380
Efficient Content Optimization with Google Search Console & Apps Script
katarinadahlin
PRO
1
910
Unlocking the hidden potential of vector embeddings in international SEO
frankvandijk
0
970
VelocityConf: Rendering Performance Case Studies
addyosmani
331
25k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
50
10k
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