Производительность CSS — как оценить — анимация (переход) размера плавающей кнопки при прокрутке (масштаб преобразования по высоте/ширине)

Вводная информация: я сделал фиксированную кнопку меню, чтобы отображать меню навигации при использовании мобильного устройства. Для этого приложения я использую сценарий Headroom.js, чтобы уменьшить размер кнопки при прокрутке вниз, чтобы она не блокировала слишком много содержимого. Анимация/переход применяется путем добавления класса с заданными изменениями.

В исходном методе я изменил размер и внешний вид кнопки, изменив height/width родительского элемента и padding дочернего элемента с помощью CSS (и перехода css).

Новый метод, который, как я читал, может/должен быть лучше на разных сайтах, заключается в изменении размера кнопки с помощью transform: scale(). Обратите внимание, что я также немного перемещаю элемент, также применяя translate3d(20px,20px,0) в этом методе. Тем не менее, он чувствует себя немного более плавным при прокрутке с использованием метода transform: scale() (хотя это может быть эффект плацебо), но использование временной шкалы инструментов chrome dev дает мне, казалось бы, неубедительные результаты.

Поэтому часть моего вопроса также заключается в том, как я должен оценивать лучший метод. Является ли временная шкала в инструментах Chrome Dev лучшим вариантом или есть лучший способ сделать это? И на каких элементах временной шкалы мне следует основывать свой выбор? и еще один вопрос, основанный на вашей интерпретации изображений и/или тестов в сочетании с вашими знаниями, какой метод работает лучше всего (или должен работать лучше всего в теории)?

Ниже вы можете увидеть два примера временной шкалы для каждого метода. Изменение высоты/ширины и заполнения (исходный метод): Метод высоты/ширины






Метод с использованием transform: scale() для изменения размера:

Метод преобразования масштаба

Также вы можете попробовать разные методы в скриптах здесь:
ссылка: Исходный метод изменения высоты/ширины и заполнения
ссылка на новый метод: с использованием transform:scale

Пожалуйста, не обращайте внимания на плохое расположение всего; особенно кнопка. Уродливое изображение внутри кнопки меню просто для того, чтобы показать, что изображение включено в макет на моей собственной странице, и принять это во внимание с точки зрения производительности. Изображения сзади также включены, так как это интернет-магазин с большим количеством изображений, которые могут повлиять на производительность.

CSS для добавленного класса, который вносит изменения в исходный метод:

.mobile-nav.headroom--unpinned {
    height: 40px;
    width: 40px;
}
.headroom--unpinned .mobile-content{
  padding-top:4px;
}


CSS для добавленного класса с использованием transform:scale():

.mobile-nav.headroom--unpinned {
transform:scale(.5) translate3d(20px,20px,0);
}


Итак, резюмируя мои вопросы:
Как мне оценить, какие методы имеют наилучшую производительность, и какой метод, по вашему мнению, работает лучше всего?

Последнее замечание: я знаю, что методы разные (анимация разных вещей и большего количества элементов в исходном методе), но это 2 варианта, которые я предпочитаю на данный момент.


person Chri.s    schedule 14.03.2017    source источник


Ответы (1)


Я полагаю, вы упускаете суть, Крис: причина, по которой никакое другое свойство, кроме transform и opacity, никогда не должно анимироваться, заключается в том, что они не вызывают перерисовку ни в чем другом, даже если элемент находится в потоке документа (и потому, что вы можно сделать что угодно только с этими двумя в 95% случаев).

С точки зрения эффективности существует два типа анимации:

  • те, которые вызывают перерисовку в других элементах, кроме анимированного элемента
  • те, которые этого не делают.

Это основная причина, по которой мы рекомендуем анимации от transform, opacity или position:relative;left|right|top|left. Потому что они на самом деле не перемещают элемент в потоке, поэтому не вызывают перерисовку каждого отдельного элемента в потоке после анимируемого.

Теперь, если указанный родитель был позиционирован абсолютно (что, как я предполагаю, имеет место), он в любом случае не вызвал бы перерисовку остальной части DOM, поэтому различия между этим методом и transform были бы незначительными. Неубедительно, как вы выразились. Теоретически перерисовка двух элементов вместо одного должна быть медленнее.

Если вам нужно протестировать, создайте 10 тысяч клонов и включите анимацию для всех них с каждым методом.

Это будет решающим.


Если вы действительно хотите min-max этого (например, тратить абсурдное количество времени на едва заметные улучшения, как я), вы найдете множество ресурсов, которые порекомендуют:

  • замена любых .animate() на .velocity()
  • никогда не анимирует ничего, кроме transform или opacity, хотя Velocity утверждает, что они анимируют что угодно без ущерба для производительности (в лучшем случае я нахожу это спорным/спорным) - но это чистое улучшение по сравнению с .animate()
  • придерживаться CSS переходов, если это возможно (в основном, если вам не нужны цепочки)
  • с помощью API веб-анимации

Личный совет: никогда не рассчитывайте на синхронизированные CSS анимации, особенно если у вас их много. Если вы меняете вкладки или система какое-то время делает что-то чрезвычайно ресурсоемкое, ваши анимации будут далеко. Если вам нужны цепи, цепь.

person tao    schedule 14.03.2017
comment
Спасибо за ответ Андрей! Ваше описание моих неубедительных выводов очень помогает. Честно говоря, я знал, что absolute/fixed (в моем случае position: fixed) уберет его из потока документов, но я просто не подумал об этом и посчитал, что он даст аналогичные результаты, несмотря на разные анимации, поскольку он уже был удален. потока. - person Chri.s; 15.03.2017
comment
В конце очень долгого дня здесь. Каждый раз, когда я имел в виду transform. Я связываю эти два, потому что в CSS вы идете transition: transform duration easing delay. Виноват. - person tao; 15.03.2017
comment
Ха-ха, не беспокойся! Просто хотел убедиться :) Также примечание: к сожалению, я немного похож на вас, пытаясь максимизировать производительность; и это несмотря на мои несколько ограниченные знания о том, что стоит за фактическими свойствами CSS/JavaScript, что приводит к тому, что довольно много часов тратится на несколько ограниченные улучшения :) - person Chri.s; 15.03.2017
comment
Собственно, это единственный способ научиться. И тестирование. Когда я сказал клонирование 10 000 элементов, я имел в виду именно это. я делаю это много. Кроме того, поскольку я хочу, чтобы мои анимации были идеальными, я обычно создаю их на скорости в 10 раз медленнее, просто чтобы убедиться, а затем снизить их до нормальной скорости. У тебя хороший подход. Вы будете в курсе в кратчайшие сроки. Ваше здоровье! - person tao; 15.03.2017
comment
На самом деле я воспринял это буквально, так как я видел аналогичные тесты, так что не беспокойтесь :) Я думаю, что буду придерживаться решения transform:, учитывая ваш ответ и различные другие источники. Однако, несмотря на мои неубедительные результаты, может показаться, что добавление translate3d(20px,20px,0) к transform: немного снижает производительность - можете ли вы объяснить это? Редактировать: это из-за движения по другому контенту, заставляющего его перекрашивать? Учитывая, что это вне потока, я бы не ожидал этого, но я не уверен. - person Chri.s; 15.03.2017
comment
@Chri.s Это зависит как от браузера, так и от версии. Это также зависит от того, переключаетесь ли вы с 2D-рендеринга на 3D-рендеринг для текущего преобразования и от того, переводит ли используемый браузер/версия текущее преобразование в матрицу или нет. Некоторые производители заметили, что им не нужен этот перевод (что обеспечивает гибкость и делает возможным объединение очень сложных преобразований). Поэтому они делают это только тогда, когда это необходимо, а не всегда. - person tao; 15.03.2017
comment
Спасибо за ответ. Я добавил translate3d перед фактическим изменением, поэтому он просто меняет значение this. - person Chri.s; 15.03.2017