CSS `will-change` - как это использовать, как это работает

Я нашел CSS will-change W3.org docs, свойство MDN docs (которое уже работает в Chrome и частично поддерживается Firefox и Opera), но я не совсем уверен, как это работает. Кто-нибудь знает что-то еще об этой загадочной вещи?

Я только что прочитал, что это позволяет браузеру подготовиться к расчету по элементу в будущем. Я не хочу неправильно понять это. Итак, у меня есть несколько вопросов.

  1. Должен ли я добавить это свойство в класс элемента или его состояние при наведении?

    .my-class{
        will-change: 'opacity, transform'
    }
    .my-class:hover{
        opacity: 0.5
    }
    .my-class:active{
        transform: rotate(5deg);
    }
    

    ИЛИ ЖЕ

    .my-class{
        ...
    }
    .my-class:hover{
        will-change: 'opacity'
        opacity: 0.5
    }
    .my-class:active{
        will-change: 'transform'
        transform: rotate(5deg);
    }
    
  2. Как это может увеличить производительность браузера? Теоретически, когда CSS загружен, браузер уже "знает", что будет с каждым элементом, не так ли?

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

7 ответов

Решение

Я не буду копировать вставлять всю статью здесь, но вот версия tl;dr:

Указание того, что именно вы хотите изменить, позволяет браузеру принимать более обоснованные решения относительно тех оптимизаций, которые необходимо выполнить для этих конкретных изменений. Это, очевидно, лучший способ повысить скорость, не прибегая к взлому и не заставляя браузер создавать слои, которые могут быть или не быть необходимыми или полезными.

Как это использовать:

will-change: transform, opacity;

Как не использовать это:

will-change: all;

.potato:hover {
  will-change: opacity;
  opacity:1;
}

Определение will-change на зависание не влияет:

Установка will-change для элемента непосредственно перед его изменением практически не имеет никакого эффекта. (Это может быть на самом деле хуже, чем вообще не устанавливать его. Вы можете понести стоимость нового слоя, если то, что вы анимируете, ранее не соответствовало требованиям для нового слоя!)

Я потратил некоторое время на поиск, как will-change собственность работает и как мы ее используем. Надеюсь, будет полезным резюме. Спасибо всем за ответы.

1. Layers Hack / Null Transform Hack

В "древние времена" (как 2 года назад) кто-то обнаружил, что вы можете рисовать CSS-анимацию быстрее.

Как это работает?

Если вы добавите transform: translateZ(0) в селектор CSS, это заставит браузер переместить элемент с этим селектором в новый слой композитора. Более того, это повысит производительность (в большинстве случаев используйте мощности GPU вместо CPU), подробнее читайте здесь.

2. До свидания, хаки, добро пожаловать "изменится":

Возможно, пока рано говорить "До свидания" с Layer Hack, но это время скоро придет. Новая недвижимость will change появился в спецификациях CSS и станет отличным наследником взлома слоев.

3. Поддержка браузера

На данный момент он доступен в Chrome и Opera, а также частично поддерживается Firefox.

4. Как правильно его использовать

Не используйте will-change где-либо в вашем CSS, пока не завершите реализацию анимации. Только тогда вы должны вернуться к своему CSS и применить will-change. Больше

Это, наверное, самый ценный совет, который вы можете получить.

Нет смысла использовать его непосредственно перед началом действия, например, добавив его в :hover состояние селектора. Потому что браузеру не понадобится время для подготовки оптимизации до появления изменений. Браузеру понадобится ок. 200 мс, чтобы применить оптимизацию, так, например, лучше добавить will-change к элементу, когда родительский элемент находится в состоянии наведения. Больше

Пример:

 .parent:hover .change{
     will-change: opacity;
 }
 .change:hover{
    opacity: .5;
 }

Вы должны использовать это действительно экономно. Если вы хотите все оптимизировать, результаты будут противоположны ожидаемым. will-change заставляет браузер держать оптимизацию включенной и резервировать ресурсы, такие как память, для изменений в будущем, которые могут никогда не произойти. Рекомендуется выключить will-change потом, когда это больше не нужно, например, когда анимация закончена.

Вы можете сделать это легко, используя JavaScript document.getElementById('my_element_id').style.willChange = off;

Теперь с помощью CSS вы можете создавать различные анимации, и иногда эта анимация становится узким местом для процессора. Поэтому вместо того, чтобы выполнять эту работу на процессоре, было бы неплохо использовать графический процессор для этой задачи. И не так давно люди начали использовать трюк, чтобы сделать это для 2D-преобразования, выполнив что-то вроде:

.accelerate {
  -webkit-transform: translate3d(0, 0, 0);
}

Это заставило браузер думать, что он выполняет 3D-преобразование, и, поскольку все 3D-преобразования используют GPU, это разгрузит CPU. Это выглядит неприлично (потому что на самом деле это так) и will-change Свойство изменит это, сообщив браузеру, что нужно следить за изменениями в будущем, и соответственно оптимизировать и распределять память.

На основе проекта W3C,

CSS-свойство will-change… позволяет автору заранее информировать UA о том, какие изменения они могут внести в элемент. Это позволяет агенту UA заранее оптимизировать обработку элемента, выполняя потенциально дорогостоящую работу по подготовке анимации до ее фактического запуска.

Хорошая идея для использования will-change это сообщить браузеру заранее, какие изменения в элементе можно ожидать. Это позволяет браузеру заранее произвести правильную оптимизацию, что приводит к более быстрой визуализации.

Эта информация была взята из этого превосходного объяснения о will-change имущество. В статье есть дополнительный пример, когда его приятно использовать, и когда он бесполезен или даже вреден

Насколько я знаю...

  1. Это альтернатива для translate-z:0.
  2. Я не знаю о hover, но на самом деле лучше всего использовать его на свойствах, которые постепенно меняются с помощью JS, изменения непрозрачности, положения при прокрутке и т. Д.
  3. Это свойство не следует использовать слишком часто, особенно на телефонах и планшетах. Использование этого слишком большого количества элементов может вызвать проблемы с производительностью.
  4. Рекомендуется удалить / отключить это свойство JS, когда оно больше не актуально.

Таким образом, пример использования будет применять это в какой-то момент прокрутки с scrollTop:400, затем постепенно анимировать непрозрачность и, скажем, scrollTop:500, снова отключить will-change.

Источник: подкаст shoptalkshow - они упоминают эту статью - https://dev.opera.com/articles/css-will-change-property/ - которая, вероятно, является лучшим источником информации, чем мой пост:D

Благодаря will-changeСвойство CSS мы можем объявить браузеру о нашем намерении изменить элемент:

  • contents,
  • scroll-position,
  • различные свойства тегов, такие как transform или opacity,
  • объявить сразу несколько значений: will-change: transform, opacity, top;

или убрав специальную оптимизацию, используя значение auto.

Это позволяет браузеру планировать использование GPU/аппаратного ускорения вместо стандартного использования ЦП.

Но мы должны использовать это с умом. Нам нужно:

  • чтобы передать это элементу, который изменится,
  • назначить его достаточно рано, до того, как произойдет изменение,
  • удалите его из элемента, который изменился и больше не будет.

Примечание из веб-документов MDN:

will-changeпредназначен для использования в крайнем случае, чтобы попытаться решить существующие проблемы с производительностью. Его не следует использовать для прогнозирования проблем с производительностью.

Они также упоминают, что если мы решим использовать will-changeсвойство, мы не должны устанавливать его жестко в таблице стилей CSS, потому что это, вероятно, заставит браузер сохранять оптимизацию в памяти намного дольше, чем это необходимо... Лучше использовать это свойство непосредственно из JavaScript (есть также пример с этим).

Хороший дополнительный ресурс для более глубокого изучения этой темы: все, что вам нужно знать о свойстве CSS will-change.

Я использую пакет реактивного окна, и есть «изменение: преобразование»; свойство на внешнем div. Пакет динамически отображает части большого набора данных в видимом представлении в соответствии с положением прокрутки, например, отображает только 10 элементов из списка длиной 100 000. Без свойства will-change список будет пустым при прокрутке. На слабом процессоре лучше показывает.

Вы можете увидеть пример здесь: react-window-fixed-size-list-vertical . Откройте инструмент разработчика, снимите этот флажок в стилях, замедлите процессор на вкладке «Производительность» и быстро прокрутите список. пустой список между рендерами

Также есть обсуждение. https://github.com/bvaughn/react-window/issues/47

Лучшее решение для меня:

transform : translate(calc(-50% + 0.5px), calc(-50% + 0.5px));

Но у этого решения есть проблемы с calc в ios safari в фиксированном положении, что может привести к высокому расходу заряда батареи.

Другие вопросы по тегам