Can SVG animations use less CPU?
Animated SVGs have become very popular in web design, and for good reason: they make art easier to translate from designer to developer, they’re light-weight in terms of filesize, and they’re just plain pretty to look at.
As with the hero of any story, however, there must be a fall from grace. For animated SVGs, this fall occurs in CPU usage. The inclusion of just a few on a webpage can cause the CPU usage of a browser to jump by several tens of percentage points. Viewing such a page on even modern laptops will cause the machine to whirr like it’s trying to take flight and heat up like a bacon griddle.
Fortunately, redemption for our hero comes easily and quickly in the form of CSS hardware acceleration.
If you’re unfamiliar with the concept, the idea is to give a troublesome element the style
transform: translateZ(0);. This gives the element its own render layer, and lets the GPU (who’s better at this kind of work anyway) take the hard number crunching away from the overloaded CPU.
Let’s say you had a piece of your webpage with both animated and static SVG elements. The simplest way to organize them, HTML-wise, is to wrap them all in a single
<svg/> tag, like this:
<svg> <g class="static-elements"></g> <g class="animated-elements"></g> </svg>
However, because 3D transforms cannot be used on SVG elements (like
<g/>), the closest element that can take the
transform: translateZ(0); style is the
<svg/> element itself. This is pointless, because the static and animated SVG elements are still all in one render layer, and the browser still has to work through every static element whenever it wants to repaint an animated one.
Instead, the static and animated SVG elements should be split up into separate
<svg/> tags, like this:
<svg class="static"> <g class="static-elements"></g> </svg> <svg class="animated"> <g class="animated-elements"></g> </svg>
There! Now we can use hardware acceleration on
svg.animated specifically. For a typical SVG, splitting up the static and animated elements like this can take the CPU/GPU usage from this CPU-intensive my-computer-is-burning-up state:
Note how Chrome is using 120% of the CPU, but only 11MB out of 512MB on the GPU
to this much more energy efficient state:
Now Chrome is using only 30% of the CPU, and more than trebled its GPU usage to 41MB
The only tricky bit is to make sure our two
<svg/> tags line up, but this can be accomplished with any one of a number of tricks (negative margin, absolute positioning, etc.).
This is one of those fascinating moments where a little thoughtful coding can lead to enormous real-world and human consequences. In this case, the effects range from massively reduced energy consumption and increased hardware lifetime for users with modern machines, to the ability to view the website at all for users with older computers. The HTML and CSS become more complicated, yes. But in my opinion, complex and usable is preferable to its inverse.