Offloading SVG transitions to the GPU using layers
Previously I wrote about leveraging steps()
in CSS animations to enhance SVG transitions performance by essentially "lowering the framerate" of the transition. This worked well, but ultimately it wasn't enough, because CSS fill
isn't GPU accellerated. In order to get silky smooth fading between two complex SVGs, I needed to make sure work was being offloaded to the GPU.
In modern browsers (although some filter
properties are now supported) basically only opacity
and transform
are GPU accelerated. So we can transition between multiple layers using opacity
.
Here's the basic idea. First we have two SVGs.
<!-- Bottom SVG Layer -->
<!-- Top SVG Layer -->
Then we layer the SVGs on top of each other using CSS and animate the top layer's opacity.
}
}
}
}
{
0% }
100% }
}
And there you have it! A GPU accelerated transition between two SVGs. Here's a live version.
You could even use steps()
to reduce the frequency of opacity changes. Or else tie the opacity to a throttled scroll position or mouse position to create a more interactive experience.
For additional reading check out this excellent article from Smashing Magazine called CSS GPU Animation: Doing It Right
Anyway that's it. Have fun!
ps. if your SVGs are really huge and complex (like mine were), you can even dynamically render them to a canvas element first at the correct DPI, but that's a subject for another time.