Сколько миллисекунд нужно для отрисовки кадра без торможения

Ответ

Для плавной анимации без торможений кадр должен отрисовываться за 16.67 мс (1000 мс / 60 FPS). Это стандартный целевой показатель для 60 кадров в секунду.

На Android важно учитывать:

  • Время рендеринга UI (measure/layout/draw)
  • Время выполнения бизнес-логики в UI потоке
  • Время GPU-рендеринга

Пример проверки производительности:

class MyView : View {
    override fun onDraw(canvas: Canvas) {
        val startTime = System.nanoTime()
        // Рисуем контент
        val renderTime = (System.nanoTime() - startTime) / 1_000_000
        if (renderTime > 16) {
            Log.w("Perf", "Slow rendering: ${renderTime}ms")
        }
    }
}

Ответ 18+ 🔞

А, ну это же классика, ёпта! Слушай, если хочешь, чтобы твоя анимация летала как угорелая, а не дёргалась, будто кот под кайфом, то тебе нужно уложиться в 16.67 миллисекунд на кадр. Это, блядь, священный грааль для шестидесятки кадров в секунду. Меньше — хорошо, больше — начинается пиздец, и пользователь уже чувствует, что что-то не так, хотя, может, и не поймёт, что именно.

Теперь про андроид, тут, чувак, подводных камней — овердохуища. Главное — не накосячить в трёх местах, а то будет тебе хиросима, а не интерфейс.

Во-первых, это сам UI. Эта хуйня с measure, layout и draw. Если у тебя вьюхи вложены, как матрёшки, и ещё с кучей сложной логики в onDraw — пиши пропало. Оно будет считать эти размеры до второго пришествия.

Во-вторых, твоя бизнес-логика, которую ты, гений, запихнул в UI-поток. Сеть там дергаешь, в базу тяжелые запросы шлёшь, или, ядрёна вошь, JSON на десять мегабайт парсишь прямо в главном потоке. После этого не удивляйся, что анимация встала колом. Терпения ноль ебать у системы, она просто выкинет ANR, и пользователь тебе в душу бога мать пошлёт.

В-третьих, GPU. Ты можешь нарисовать всё быстро, но если там сложнейшие шейдеры, куча оверлеев и прозрачностей — GPU будет вздрачивать эту сцену дольше, чем ты думаешь.

Вот, смотри, простейший способ проверить, не говнюк ли ты код написал. Кидаешь замер прямо в onDraw:

class MyView : View {
    override fun onDraw(canvas: Canvas) {
        val startTime = System.nanoTime()
        // Тут твой гениальный, но возможно, ебанько-код, который рисует радугу и десять слоёв тени
        val renderTime = (System.nanoTime() - startTime) / 1_000_000
        if (renderTime > 16) {
            Log.w("Perf", "Slow rendering: ${renderTime}ms")
        }
    }
}

Если в логах начало сыпаться предупреждение — всё, чувак, подозрение ебать чувствую. Твой рендеринг — сосалка, и пора лезть в профайлер, смотреть, где оно там бутылочное горлышко. Иначе получишь не плавный скролл, а слайд-шоу, от которого глаза вытекают.