Optimizing CSS animations across devices is more important than ever. Learn the secret to minimising rendering work for smoother transitions here.
Today’s users of the web expect a smooth experience, whether they are accessing via desktop or mobile. Given that CPUs of mobile devices are significantly less powerful than their desktop counterparts, failing to optimise the code of CSS animations for mobile can deliver a slow or compromised performance. Therefore, it is critical to ensure your CSS transitions are low-cost, fully accessible and run quickly across all devices.
To do this, you’ll need to understand exactly how your CSS transitions are rendered by your individual browser. By grasping the steps undertaken to ship frame to screen within the Pixel Pipeline, you can comprehend which of those steps are triggered by changing properties within your animation. This enables you to enhance the performance of your transition by eliminating steps of the pipeline altogether. You can learn which steps your CSS property triggers in each browser here, and check which properties are being animated here.
Your browser then calculates which CSS rules apply to which elements based on matching selectors. Once these rules are known, the final styles for each element can be calculated.
Your browser then starts to determine the shape and positioning of the elements, calculating the geometry of those elements.
Changes to the geometric properties such as width and height, left and right all trigger layout operations. It’s important to realise that animating an element’s position can affect the geometry of others, meaning your browser needs to check all elements, and reflow the page, which can be expensive. Affected areas then need to be repainted and the finalised elements composited back together. For instance, when you animate an element with a container, be wary of changing the child elements that live on that container too. In general, in your transition, it is better to refrain from animating properties that trigger these layout operations, which can be costly and result in a sub-par performance for your CSS transition.
Painting is the process by which your browser fills in pixels into different layers, drawing out text, colors, images, and borders that are then composited to a screen.
Triggering a paint property in your CSS transition is not recommended, as it can be the most expensive part of the Pixel Pipeline. This can cause all layers to change, necessitating re-painting which is particularly expensive for mobile devices that don’t have the same memory or CPU power as desktops. To optimise your transition experience, the browser should ensure that the animated CSS doesn’t cause a repaint.
After all your layers have been painted, you need to position them. Compositing involves deciding where to place things on the screen, and in which order, so the page renders correctly.
The most effective way to avoid excess work for your CPU is to animate low-cost properties that only affect compositing - those being transform and opacity. A key concept to remember is that for the use of transform and opacity, the element on which properties are changed needs its own compositor layer.
In Blink and WebKit browsers, new layers are automatically created for elements with CSS transitions on opacity, but many developers choose to employ translateZ(0) or translate3d(0,0,0) to manually force layer creation. This means your browser can prepare itself by pre-creating compositor layers, bypassing the layout render or painting in the process. This ensures that the layer is already ready to go when the animation starts (so there won’t be delays to your transition).
This technique can be visualized in terms of travel. The more stops you make on a journey, the more likely it is to be disrupted. Similarly, in progressing straight to the composite and removing rendering stages, you reduce the potential for skipped frames and a negative user experience, much like a hassle-free direct flight.