Как оптимизировать анимацию?

На смартфоне при использовании такой анимции проседают кадры. Как оптимизировать такую анимацию?

* {
  box-sizing: border-box;
}

body {
  font-family: sans-serif;
}

.box {
  width: 300px;
  padding: 10px;
  background: #e2e2e2;
  position: relative;
}

.box p {
  margin-bottom: 200px;
  transition: margin-bottom .5s;
}

.box-image {
  position: absolute;
  width: 100%;
  height: 200px;
  background-image: url(http://wemodern.xyz/images/photo_2019-09-28_22-31-17.jpg);
  background-position: top center;
  background-size: cover;
  bottom: 0;
  left: 0;
  transition: height .5s;
}

.nav-deploy {
  position: absolute;
  bottom: 10px;
  left: 50%;
  margin-left: -50px;
  z-index: 2;
  color: white;
  width: 100px;
  background: rgba(0, 0, 0, 0.63);
  text-align: center;
}

#nav-deploy-check {
  position: absolute;
  bottom: 8px;
  left: 50%;
  width: 100px;
  margin-left: -50px;
  z-index: 3;
  height: 22px;
  cursor: pointer;
  opacity: 0;
}

#nav-deploy-check:checked~.box-image {
  height: 600px;
  transition: height .5s;
}

#nav-deploy-check:checked~p {
  margin-bottom: 600px;
  transition: margin-bottom .5s;
}
<div class="wrapper">
  <div class="box">
    <input type="checkbox" id="nav-deploy-check">
    <div class="nav-deploy">Развернуть</div>
    <h3>Lorem ipsum.</h3>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Consequatur similique quod omnis
    </p>
    <div class="box-image"></div>
  </div>
</div>


Ответы (3 шт):

Автор решения: Инквизитор
  1. Купить смартфон помощнее.
  2. Не насиловать несчастный недобраузер смартфона громоздкими пересчетами больших картинок.
  3. Попробовать анимировать не саму картинку, а некий элемент, например, <div>, которому задавать нужные размеры, а картинку задать ему в качестве фона, проставив нужные значения свойства background-size, например, 100% auto.

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

Примерно так:

.parent_container {
  height:600px;
  ...
  transition-duration: 0.5s;
}

.image_container {
  height:600px;
  ...
  transition-duration: 0.5s;
  transform-origin: top center;
}

.parent_container.transformed {
  height:200px;
}

.parent_container.transformed .image_container {
  transform:scale(calc 600px / 200px);
  ...
}
→ Ссылка
Автор решения: Node_pro

Определенная часть анимации на телефоне не возможно довести до нормального состояния, не обращая внимания на их простоту. Однако следующие советы могут помочь:

  1. Используйте transform, где возможно, а желательно с 3d, даже если Вам не нужен 3d. Например, для передвижение элементов используйте translate3d(-100%, 0, 0);.
  2. Используйте вместо opacity => filter: opacity()
  3. Делайте специальные изображения для мобильных телефонов. Оптимизируйте их максимально.
  4. Добавьте will-change: transform; там где будите использовать transform.
  5. Отключение pointer-events, где это возможно, может положительный результат
→ Ссылка
Автор решения: Sasha Omelchenko

Если у вас этот блок не висит сферически в вакууме, а плавно сдвигает вниз какой-либо контент, то кадры могут проседать даже после хорошей оптимизации. Происходить это будет из-за того, что каждый кадр будет вызывать Relayout в конвейере пикселей, а это дорогая процедура. Что можно сделать по вашей анимации конкретно - как минимум переверстать так, чтобы убрать transition: margin-bottom .5s, поскольку это одно из самых дорогих для анимации свойств. Советы выше тоже в целом хорошие, я бы лишь добавил, что стоит стремиться к тому, чтобы иметь возможность анимировать только свойства transform и opacity.

→ Ссылка