Формат строк: now avg peak (мс) — текущий кадр, среднее по окну (по умолчанию 120 кадров), пик с
последнего reset. other и pipe собраны из других строк, поэтому заканчиваются на avg:
собственного пика у них нет.
Бюджет кадра: FrameMetrics.DEADLINE (API 31+, столько система выделила кадру) или
1000 / refreshRate. На 60 Гц это 16.7 мс. Бюджет из frameBudgetsMs встаёт на его место. Тот
бюджет, что действует сейчас, показан в заголовке.
На статичном экране показатели замирают. Кадров нет, отчитываться не о чем.
Панель перетаскивается пальцем. Тап переключает три вида ниже, long-press — freeze: показания замирают для чтения, сбор продолжается.
| Вид | Что показывает |
|---|---|
| Полный | Все строки этой страницы, вплоть до сессии, памяти, температуры и ваших счётчиков |
| Кадр | Вердикт, фазы, которыми управляет приложение, TOTAL и сводку окна |
| Одна строка | Спарклайн, FPS, jank и фазу-виновника |
Вид кадра не показывает стадии render и GPU, over и pipe. Приложение ими напрямую не
управляет, а если проблема именно там — об этом говорит вердикт первой строкой.
В шапке три кнопки. ⧉ запрашивает разрешение на оверлей и видна, только пока панель заперта
в окне приложения. ▤ переключает между показаниями и худшими экранами. × — reset окна,
сессии и пиков.
idle — кадров нет: статичный экран
или замёрзший main threadРабота UI-потока, где живёт весь Compose и View-код приложения.
| Строка | Что покрывает | Растёт когда |
|---|---|---|
input |
Обработка тач-событий и клавиш, включая все onClick/onTouch коллбэки | В обработчиках тяжёлая логика |
anim |
Расчёт текущих значений анимаций (Animatable, animate*AsState, Transition) |
Много одновременных анимаций |
layout |
Measure + layout всех View и Composable | Глубокая иерархия, частые рекомпозиции, intrinsic measurements |
draw |
Запись draw-команд в DisplayList (Canvas.draw*, текст, фоны) |
Много элементов на экране |
Отдельный поток Android, который берёт DisplayList от UI-потока и превращает в GPU-инструкции.
| Строка | Что покрывает | Растёт когда |
|---|---|---|
sync |
Синхронизация DisplayList из UI-потока + загрузка bitmap’ов как GPU-текстур | Большие или новые картинки |
command |
Преобразование draw-команд в OpenGL/Vulkan вызовы и отправка на GPU | Сложная иерархия View, много слоёв |
swap |
Ожидание пока GPU закончит предыдущий кадр + вывод на экран (eglSwapBuffers) |
GPU перегружен |
gpu — сколько GPU тратит на растеризацию кадра: шейдеры, отрисовка текстур, блендинг слоёв.
Нужен Android 12+ (API 31) и драйвер, который эти тайминги отдаёт. Пока реальных значений нет, в
строке n/a: часть драйверов их так и не присылает.
delay: время от vsync-сигнала до реального начала работы над кадром. Растёт когда main thread
занят чем-то другим: тяжёлый callback, IO, предыдущий кадр ещё не закончилсяother: остаток TOTAL, не разнесённый по фазам. В норме около нуляTOTAL: полное время кадра от vsync до завершения. Должно быть ≤ бюджетаover: TOTAL минус бюджет, то есть перерасход кадра. Отрицательное значение = запасpipe:cpu|rt|gpu: стадия с наибольшим средним и её тайминги. Стадии работают параллельно, при
устойчивой нагрузке fps упирается в неё, а не в TOTALframeBudgetsMs не задал
свойfrz — frozen frames (TOTAL > 700 мс, как в Play Vitals), run —
максимальная серия jank-кадров подряд▲ — пики с reset. Ползёт вверх при навигации
туда-сюда = утечкаFrameHud.counter, по строке на каждый: значение и его пик.
Строк не больше четырёх, остальные сворачиваются в +N more countersПока открыто взаимодействие, в шапке вместо таймингов стоит ▸ имя. Это подпись к происходящему, а
не рамка для цифр: строки ниже остаются на обычном окне и сессии, и только событие MarkEnded
отчитывается по одной метке. Метку выставляет FrameHud.mark в приложении; сама панель их не ставит.
Строка под заголовком:
✓ ok: jank < 5%⚠ <фаза> N ms: фаза с наибольшим средним, включая delay; она же помечена ◀ в списке.
Жёлтый — jank 5–20%, красный — ≥ 20%. В виде одной строки — бейдж ⚠<фаза>Строки метрик: зелёный — TOTAL в бюджете, серый — норма, красный — среднее по окну выше бюджета.
FPS (цель — герцовка дисплея): зелёный — ≥ 95% от цели, серый — ≥ 75%, красный — ниже.
Jank: < 5% норм, 5–20% подлагивает, ≥ 20% лагает.
Current прыгает, это нормально. Смотреть надо на average.
×)pipe подскажут виновника| Строка | Что делать |
|---|---|
input |
Тяжёлая логика в обработчиках тачей/кликов. Вынести работу из onClick/onTouch |
anim |
Много или сложные анимации одновременно. Упростить, убрать лишние |
layout |
Рекомпозиции. remember, derivedStateOf, меньше инвалидаций |
draw |
Много элементов на экране. LazyColumn, убрать лишнее |
sync |
Тяжёлые картинки. Размеры bitmap, resize в загрузчике изображений |
command |
Слишком много draw-команд для render thread. Много слоёв, сложная иерархия |
swap |
GPU не освободился вовремя для вывода кадра. Обычно следствие тяжёлого gpu |
gpu |
GPU перегружен. Overdraw, blur, тени, alpha-слои, большие текстуры |
delay |
Main thread заблокирован. IO/network не на том потоке |
max > 100 мс при нормальном p95 |
Разовый хик, забить |
frz > 0 |
UI замерзал заметно для глаза. Искать длинную работу на main thread |
gc растёт вместе с jank |
Аллокации в горячем пути (композиция, скролл). Профилировать allocations |
mem у лимита |
Близко к OOM, искать утечку или тяжёлые кэши |
Панель рисуется в отдельном окне и в метрики измеряемого окна не попадает.
Показания искажают три вещи, и все три панель показывает сама. drop больше нуля означает, что
система выбросила отчёты, не успев доставить: avg и перцентили недосэмплированы. therm со статусом
троттлинга означает, что устройство сбросило частоты, и тайминги несравнимы с холодным замером.
EMU в шапке означает эмулятор. В отчётах эти и другие сигналы лежат рядом со статистикой как
проблемы достоверности, каждая называет цифры, которые она портит.
Эмулятор рисует через хост-машину, поэтому sync, command, swap и gpu измеряют десктопную
видеокарту и о телефоне не говорят ничего. Заголовки секций читаются как RENDER · host и
GPU · host, сами строки погашены, и вердикт их не называет. pipe их называет, когда узкое место
приходится на них, но тоже погашенным.

Осмысленным остаётся всё, за что отвечает само приложение: input, anim, layout, draw,
delay, TOTAL, jank и итоги сессии. Именно эти числа читает jank-гейт, поэтому гонять его на CI
имеет смысл, хотя рендеринг там и не устройства.
Заодно вырастает other: на эмуляторе больше времени кадра не попадает ни в одну фазу, которую
сообщает платформа, поэтому вердикт нередко указывает на этот остаток, а не на стадию.