Regular JS vs Element.animate() performance
by Brian Birtles
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.19.0/TweenMax.min.js"></script>
<div class="container">
<figure>
<img src="https://people.mozilla.org/~bbirtles/demos/jank-example/sitting-foxkeh.svg" id="gsap">
<figcaption>Regular JS</figcaption>
</figure>
<figure>
<img src="https://people.mozilla.org/~bbirtles/demos/jank-example/sitting-foxkeh.svg" id="waapi">
<figcaption><code>Element.animate()</code></figcaption>
</figure>
</div>
<div class="warning" id="unsupported" hidden>
Sorry, your browser doesn't support <a
href="https://developer.mozilla.org/docs/Web/API/Element/animate"><code>Element.animate()</code></a>
yet so we can't compare its performance 😢
</div>
CSS
html {
font-size: 20px;
font-family: sans-serif;
overflow: hidden;
}
body {
background: linear-gradient(to top, #2e5706, #5da911 46%, #7ac31a 51%, #8bd538 65%, #65e3f2 66%);
margin: 0;
height: 100vh;
}
.container {
display: flex;
margin-left: auto;
margin-right: auto;
justify-content: center;
align-items: center;
max-width: 100%;
height: 100%;
}
figure {
margin: 0 2.5rem;
}
figure img {
width: 10rem;
/* Work around Chrome bug: https://crbug.com/633021 */
display: block;
}
figcaption {
text-align: center;
font-weight: bold;
font-size: 0.8rem;
color: #ddd;
background: rgba(0,0,0,0.2);
border-radius: 1rem;
padding: 0.5rem;
}
.warning {
position: absolute;
top: 20%;
box-sizing: border-box;
width: 80%;
left: 10%;
text-align: center;
margin-left: auto;
margin-right: auto;
font-size: 1.3rem;
background: rgba(255,200,200,0.9);
border-radius: 1em;
padding: 2em;
margin: 0;
color: red;
}
@media (max-width: 600px) {
html {
font-size: 15px;
}
}
@media (max-width: 400px) {
html {
font-size: 10px;
}
}
JavaScript
if (!Element.prototype.animate) {
document.getElementById('unsupported').hidden = false;
return;
}
var gsap = document.getElementById('gsap');
TweenMax.to(gsap, 1.2, { rotation: 360,
ease: Linear.easeNone,
repeat: -1 });
var waapi = document.getElementById('waapi');
waapi.animate({ transform: [ 'rotate(0deg)', 'rotate(360deg)' ] },
{ duration: 1200, iterations: Infinity });
setTimeout(simulateGCPause, 500);
function simulateGCPause() {
var pauseLength = 50 + Math.random() * 200;
var start = window.performance.now();
while (window.performance.now() - start < pauseLength);
var interval = 200 + Math.random() * 700;
setTimeout(simulateGCPause, interval);
}