Reputation: 3512
I'm working on improving a Keyframe Animation's smoothness. It seems to work perfectly on desktop but is very laggy and not smooth on mobile. How would I need to change my code to make it smooth?
See JSBin: https://jsbin.com/hecifu/6/edit?html,css,js,output
@keyframes overlayAnimation {
0% {
width: 100vw;
height: 100vh;
transform: translate3d(0px, 0px, 0);
background: transparent;
}
25%{
width: 10px;
height: 200px;
transform: translate3d(calc(50vw - 5px), calc(50vh - 100px), 0);
}
50%{
width: 10px;
height: 200px;
transform: translate3d(calc(50vw - 5px), calc(50vh - 100px), 0) rotate(90deg);
}
50.1%{
width: 200px;
height: 10px;
transform: translate3d(calc(50vw - 100px), calc(50vh - 5px), 0) rotate(0deg);
}
75%{
width: 200px;
height: 100vh;
transform: translate3d(calc(50vw - 100px), 0px, 0) rotate(0deg);
}
100%{
width: 100vw;
height: 100vh;
transform: translate3d(0px, 0px, 0) rotate(0deg);
visibility:hidden;
}
Upvotes: 0
Views: 713
Reputation: 3138
There are a few issues that could be causing the slow-down. The main suspect though: remove the box-shadow
.
To elaborate
CSS can utilise hardware acceleration for animations... but only for transform
and opacity
animations - all other animations are run on the CPU, which is less optimised: https://www.smashingmagazine.com/2016/12/gpu-animation-doing-it-right/
Your animation changes the width
and height
attributes of an element - what you may want to consider is changing it so that the size is altered via a transform: scale(x, y)
change instead: https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function/scale
But possibly the biggest drain in your animation is actually the box-shadow
- you have a box-shadow
set that is 2000px
in all directions - that is going to be quite a draw on the smartphone, which has to thus calculate (even if it doesn't have to render all of) a box that is at least 4000px
larger than the width and height of the device. Box-shadows
can be costly to render at the best of times. These documented cases are for scrolling performance, but I should imagine that animating a box-shadow
has a similar performance impact.
What might be better here is to try and use a clip-path
to clip the content, rather than cover it with a box-shadow
. That would work something like this (based on your JSBin):
var $pages = $(".page");
var $overlay = $("#overlay");
$('.page a').on("click", function(){
if($overlay.hasClass("overlayAnimation")) return;
$pages.fadeToggle(4000);
$overlay.addClass("overlayAnimation").on("animationend", function(){
$(this).removeClass("overlayAnimation");
});
});
*{margin:0; box-sizing:border-box;}
html, body{height:100%;}
h1{
font: 60px/2 Helvetica;
color: #fff;
font-weight: normal;
text-align: center;
}
.page{
position: absolute;
overflow: hidden;
width: 90vw;
height: 90vh;
top: 5vh;
left: 5vw;
color: white;
}
#page1{
background: #008562;
}
#page2{
display: none;
background: #ff8600;
}
.page a{
font-family: Helvetica;
color: #fff;
border: 2px solid #fff;
padding: 10px 15px;
display: block;
text-align: center;
margin: 0 auto;
width: 20%;
text-decoration: none;
}
#overlay{
position: fixed;
z-index:999;
width: 100vw;
height: 100vh;
}
#overlay.overlayAnimation{
animation: overlayAnimation 4s forwards;
}
@keyframes overlayAnimation {
0% {
clip-path: inset(0 0);
background: transparent;
}
25%{
clip-path: inset(calc(50% - 100px) calc(50% - 5px));
transform: rotate(0deg);
}
50%{
clip-path: inset(calc(50% - 100px) calc(50% - 5px));
transform: rotate(90deg);
}
50.1%{
clip-path: inset(calc(50% - 5px) calc(50% - 100px));
transform: rotate(0deg);
}
75%{
clip-path: inset(0 calc(50% - 100px));
}
100%{
clip-path: inset(0 0);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="overlay">
<div class="page" id="page1">
<h1>PAGE 1</h1>
<a href="#">Click here</a>
</div>
<div class="page" id="page2">
<h1>PAGE 2</h1>
<a href="#">Click here</a>
</div>
</div>
https://jsbin.com/pojewujoko/edit?html,css,js,output
Maybe give that a go, see if it is any more performant? It's certainly more elegant IMO, and makes more sense to someone viewing the code directly.
Upvotes: 1