[css-display]? Compositing, expensive things, and laziness

Prepare for some exposition.

Whenever something changes in the document tree, Blink waits for
everything affected by the change to finish responding to the change
before pushing the pixels to the screen, or doing other things such as
running animations.

For example, say you have CSS like the following:

.container .spinner {
  opacity: 1;
}
.container .expensive-content {
  opacity: 0;
}

.container.ready .spinner {
  opacity: 0;
}
.container.ready .expensive-content {
  opacity: 1;
}

* { transition: opacity 1s; }

The container holds some expensive-to-paint content - a video with a
mask and a box shadow and an animated border radius, I dunno.  When
the video sufficiently preloads, JS adds a "ready" class to the
container, which fades the spinner out and fades the content in.

As an obvious optimization, we skip painting content that is fully
transparent, so the expensive content hasn't been painted yet before
the transition triggers.  Due to our compositor design, this means
that we delay *both* transitions (for the spinner *and* the expensive
content) until the expensive content is painted and ready to start
fading in.

Sometimes, this is the behavior you want.  Often, it's not, because
you want the page to start responding immediately, not after 100ms
delay, even if this doesn't make it *complete* any faster - it
improves the perceived responsiveness.  However, CSS requires things
to be consistent and ignores the time aspect of rendering, so we can't
automatically choose the latter behavior for the author.



Now, the proposal:

We'd like to propose a way for an author to tag an element as being
"lazy" or "optional" in some sense, such that it's okay to let it lag
other things in displaying in situations like what I outline above.
This would be merely a rendering hint, with no direct effect
otherwise.

Right now, we're considering crazy hacks to let authors accomplish
this, which isn't good.  The current thinking is to divide animations
into "real" and "fake" ones, where a "fake" animation is currently
just one from "opacity:0;" to "opacity:0;".  Fake animations don't run
until the element is ready (painted), but don't delay anything else,
so you get the responsiveness.  Then, you can hook the animationStart
event to see when the "fake" animation starts, and *then* twiddle the
animation property to start the *real* fade-in animation (it starts
immediately now, since the element is painted at this point).

This is, obviously, totally crazy.  Do other browsers have similar
compositor designs?  Do implementors think that a hint like this might
be useful?  If not, we can pursue this as a proprietary property,
which at least keeps us away from crazy hacks.

~TJ

Received on Thursday, 2 May 2013 23:16:06 UTC