I recently started dabbling with the <animate>
SVG element to indefinitely animate a background pattern (by animating the x
attribute). It worked really well until I realized it’s extremely laggy on Safari for macOS and any iOS browser (Chrome, Safari etc.) despite the SVG file being just 2 KB.
I later realized I never transition height and position, since this triggers a repaint, and that it’s much better to use transform
. Luckily there’s something like animateTransform
specifically for SVG, which I implemented to animate translate
along the x axis instead of using animate
to animate x
itself. To my surprise, the animations still were just as laggy on webkit-based browsers. Safari’s developer tool (Events Timeline) shows the following:
This is after grouping by resource, and recorded without interacting with the page. Max CPU usage in this time was only 6%.
Here are the (silly) things I tried:
- Set
animateTransform { will-change: transform; }
- Same but instead of selecting
animateTransform
selecting its parent element
…and a few more things I forgot about. Anyways, the extremely laggy animations also cause other CSS transform transitions to be laggy. Now, my theory is that on webkit-based browsers, all CSS and HTML animations (is that even a thing?) get calculated by the CPU (and not by the GPU). I don’t really know how to check this for sure. But the <animate>
and <animateTransform>
elements don’t show up in the ‘Graphics’ tab of the Safari developer tools, unlike other animations.
So my question is, how do I off-load these animations to the GPU? I was thinking of trying the Web Animations API (see this Webkit blogpost), but I’m not sure if it’s good practice to use Javascript for a super simple animation. If anyone has more info on when to use CSS transitions/keyframes or the Web Animation API, I’d love to know more.