will-change

Заранее сообщаем браузеру, какие свойства у элементов будут меняться.

Время чтения: меньше 5 мин

Кратко

Скопировано

Свойство will-change позволяет заранее сообщить браузеру об изменениях (анимация, перемещение и т.д), которые могут произойти с элементом. Так браузер успеет оптимизировать выполнение этих изменений до того, как они произойдут. Это повышает скорость работы сайта.

Пример

Скопировано

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

        
          
          div {  will-change: /* значение */;}
          div {
  will-change: /* значение */;
}

        
        
          
        
      

Значения

Скопировано

Свойство will-change принимает одно из четырёх возможных значений:

  • auto — не указывает никакого конкретного свойства, браузер будет работать как обычно. Значение по умолчанию.
  • scroll-position — указывает, что ожидается изменение положения элемента при прокрутке страницы. Браузер заранее готовится и отрисовывает содержимое за пределами видимой части страницы.
  • contents — указывает, что ожидается изменение содержимого элемента. Браузер ограничивает или полностью прекращает кэширование элемента и отрисовывает его с нуля при каждом изменении его содержимого.
  • меняющееся свойство — имя свойства, которое будет изменяться (transform, opacity и т.д). Несколько свойств разделяются запятыми.

Примеры:

        
          
          div {  will-change: transform;  will-change: opacity;  will-change: top, left, bottom, right;}
          div {
  will-change: transform;
  will-change: opacity;
  will-change: top, left, bottom, right;
}

        
        
          
        
      

Подсказки

Скопировано

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

💡 will-change используется как крайнее средство, если есть видимые задержки в работе сайта.

На практике

Скопировано

Ксения Мадей советует

Скопировано

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

Такой код не сработает:

        
          
          /* Изменение элемента происхожит при наведении курсора */.element:hover {  /* нужно подготовиться к изменению, которое уже происходит, код не сработает */  will-change: transform;  transition: transform 2s;  transform: rotate(30deg) scale(1.5);}
          /* Изменение элемента происхожит при наведении курсора */
.element:hover {
  /* нужно подготовиться к изменению, которое уже происходит, код не сработает */
  will-change: transform;
  transition: transform 2s;
  transform: rotate(30deg) scale(1.5);
}

        
        
          
        
      

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

        
          
          .element {  /* правила */  transition: transform 1s ease-out;}.element:hover {  /* браузер начинает готовиться к изменению состояния */  will-change: transform;}.element:active {  /* происходит изменение состояния */  transform: rotateY(180deg);}
          .element {
  /* правила */
  transition: transform 1s ease-out;
}

.element:hover {
  /* браузер начинает готовиться к изменению состояния */
  will-change: transform;
}

.element:active {
  /* происходит изменение состояния */
  transform: rotateY(180deg);
}

        
        
          
        
      

Если изменение происходит при наведении курсора на элемент, то можно включать will-change при наведении на родительский элемент:

        
          
          .element {  transition: opacity 0.3s linear;}/* включаем will-change для элемента, когда мышка наводится на его родительский элемент */.parent:hover .element {  will-change: opacity;}/* применение изменения, когда мышка наведена на элемент */.element:hover {  opacity: 0.5;}
          .element {
  transition: opacity 0.3s linear;
}

/* включаем will-change для элемента, когда мышка наводится на его родительский элемент */
.parent:hover .element {
  will-change: opacity;
}

/* применение изменения, когда мышка наведена на элемент */
.element:hover {
  opacity: 0.5;
}

        
        
          
        
      

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

Пример назначения через JS:

        
          
          // Получаем доступ к элементу, который будет изменяться при клике по немуconst el = document.getElementById('element')// Включаем will-change при наведении курсора на элементel.addEventListener('mouseenter', hintBrowser)el.addEventListener('transitionend', removeHint)function hintBrowser() {  // Свойства, которые будут изменяться в блоке  // описания анимации и которые можно заранее оптимизировать  this.style.willChange = 'transform, opacity'}// Для отключения свойства устанавливаем ему значение по умолчаниюfunction removeHint() {  this.style.willChange = 'auto'}
          // Получаем доступ к элементу, который будет изменяться при клике по нему
const el = document.getElementById('element')

// Включаем will-change при наведении курсора на элемент
el.addEventListener('mouseenter', hintBrowser)
el.addEventListener('transitionend', removeHint)

function hintBrowser() {
  // Свойства, которые будут изменяться в блоке
  // описания анимации и которые можно заранее оптимизировать
  this.style.willChange = 'transform, opacity'
}

// Для отключения свойства устанавливаем ему значение по умолчанию
function removeHint() {
  this.style.willChange = 'auto'
}

        
        
          
        
      

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

В остальных случаях will-change лучше назначать через JS и отключать после завершения изменения элемента.