visibility: hidden animation doesn't stop painting

#41254682 Filed 2016-05-19 (crbug.com/613166) P3 / S5 Blink > Paint

Summary

A CSS animation on an element hidden with visibility: hidden keeps triggering per-frame paint invalidation work in Blink even though the element paints nothing. The animation must keep running per spec; the paint invalidation is pure overhead.

Live repro

Three animations run below: a transform spinner, a background-color pulse and a color text pulse. Toggle them between visibility: hidden, visible and display: none.

transform and background-color are composited in modern Chrome: cc has no layer to tick once the element paints nothing, so they go idle when hidden. color is not compositable -- it animates on the main thread and is the case that keeps repainting while hidden.

Each cell has its own state so the cases can be isolated: once any main-thread animation forces main frames, the other animations tick along with it and pollute the measurement. To measure one case, set the other cells to display: none.

transform: rotate()

background-color

color (main thread)

the quick brown fox jumps over the lazy dog 0123456789 the quick brown fox jumps over the lazy dog 0123456789 the quick brown fox jumps over the lazy dog 0123456789
current: all visibility: hidden (animations still running, elements invisible)

How to observe

1. Set the demo to visibility: hidden (default).

2. Click "isolate color case" (color cell hidden, composited cells display: none), then open DevTools > Performance and record a few seconds. "Frame Rendering Stats" is the wrong tool here: no frames are presented while hidden either way, so it stays quiet even on affected builds.

3. Unpatched Chrome shows per-frame main-thread rendering work (paint invalidation, pre-paint, paint) despite nothing being drawn. Set the color cell to display: none too and the timeline goes idle. Isolating a composited cell as hidden instead shows an idle timeline already: that half of the bug is fixed by compositor-driven animations.

Actual

Continuous per-frame paint work for the main-thread color animation while it is invisible (same as when it is visible).

Expected

Only style recalc remains; no paint invalidation or paint work while the element stays hidden.

Links

Issue 41254682 (formerly crbug.com/613166)