Как оптимизировать анимацию?
На смартфоне при использовании такой анимции проседают кадры. Как оптимизировать такую анимацию?
* {
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 шт):
- Купить смартфон помощнее.
- Не насиловать несчастный недобраузер смартфона громоздкими пересчетами больших картинок.
- Попробовать анимировать не саму картинку, а некий элемент, например,
<div>, которому задавать нужные размеры, а картинку задать ему в качестве фона, проставив нужные значения свойстваbackground-size, например,100% auto.
- Трансформировать весь блок с помошью
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);
...
}
Определенная часть анимации на телефоне не возможно довести до нормального состояния, не обращая внимания на их простоту. Однако следующие советы могут помочь:
- Используйте
transform, где возможно, а желательно с 3d, даже если Вам не нужен 3d. Например, для передвижение элементов используйтеtranslate3d(-100%, 0, 0);. - Используйте вместо opacity => filter: opacity()
- Делайте специальные изображения для мобильных телефонов. Оптимизируйте их максимально.
- Добавьте
will-change: transform;там где будите использоватьtransform. - Отключение
pointer-events, где это возможно, может положительный результат
Если у вас этот блок не висит сферически в вакууме, а плавно сдвигает вниз какой-либо контент, то кадры могут проседать даже после хорошей оптимизации. Происходить это будет из-за того, что каждый кадр будет вызывать Relayout в конвейере пикселей, а это дорогая процедура. Что можно сделать по вашей анимации конкретно - как минимум переверстать так, чтобы убрать transition: margin-bottom .5s, поскольку это одно из самых дорогих для анимации свойств. Советы выше тоже в целом хорошие, я бы лишь добавил, что стоит стремиться к тому, чтобы иметь возможность анимировать только свойства transform и opacity.