Re: [HTML Imports]: Sync, async, -ish?

On Wed, Nov 27, 2013 at 9:46 AM, Dimitri Glazkov <dglazkov@google.com>wrote:

> Stepping back a bit, I think we're struggling to ignore the elephant in
> the room. This elephant is the fact that there's no specification (or API)
> that defines (or provides facilities to control) when rendering happens.
> And for that matter, what rendering means.
>
> The original reason why <script> blocks execution until imports are loaded
> was not even related to rendering. It was a simple solution to an ordering
> problem -- if I am inside a <script> block, I am assured that any script
> before it had also run (whether it came from imports or not). It's the same
> reason why ES modules need a new HTML element (or script type at the very
> list).
>
> Blocking rendering was as a side effect, since we simply took the plumbing
> from stylesheets.
>
> Then, events took a bewildering turn. Suddenly, this side effect turned
> into a feature/bug and now we're knee-deep in the sync-vs-async argument.
>  And that's why all solutions look bad.
>
> With "elements" attribute, we're letting the user of the import pick the
> poison they prefer (would you like your page to be slow or would you rather
> it flash spastically?)
>
> With "sync" or "async" attribute, we're faced with an enormous
> responsibility of predicting the "right" default for a new feature. Might
> as well flip a coin there.
>
> I say we call out the elephant.
>

Agree entirely. Most any time we get into a situation where the UA can't
"do the right thing" it's because we're trying to have a debate without all
the information. There's a big role for us to play in setting defaults one
way or the other, particularly when they have knock-on optimization
effects, but that's something we know how to do.


> We need an API to control when things appear on screen. Especially, when
> things _first_ appear on screen.
>

+1000!!!

I'll take a stab at it. To prevent running afoul of existing heuristics in
runtimes regarding paint, I suggest this be declarative. That keeps us from
blocking anything based on a <script> element. To get the engine into the
right mode as early as possible, I also suggest it be an attribute on an
early element (<html>, <link>, or <meta>). Using <meta http-equiv="...">
gives us a hook into possibly exposing the switch as an HTTP header,
although it makes any API less natural as we don't then have a place in the
DOM to hang it from.

In terms of API capabilities, we can cut this a couple of ways (not
entirely exclusive):


   1. Explicit paint control, all the time, every time. This is very unlike
   the current model and, on pages that opt into it, would make them entirely
   dependent on JS for getting things on screens.
      1. This opens up a question of scoping: should all paints be blocked?
      Only for some elements? Should layouts be delayed until paints are
      requested? Since layouts are difficult to scope, what does paint scoping
      mean for them?
      2. An alternative might be a flag that's a one-time edge trigger:
      something that delays the *first* paint and, via an API, perhaps other
      upcoming paints, but which does not block the course of regular
      painting/layout.
      3. We would want to ensure that any API doesn't lock us into a
      contract of running code when a page is hidden doesn't actually
need to be
      repainted (based on layout invalidation, etc.) or is hidden.
   2. Some sort of a "paint threshold" value (in ms) that defines how
   quickly the system should try to call back into script to kick off a paint
   and a timeout value for how long it should wait before painting anyway.
   Could be combined with #1.

A first cut that takes some (but not all) of this into account might look
like:

<html paintpolicy="explicit"> <!-- defaults to "implicit" -->
  ...

  <script>

    // Explicit first-paint which switches
    // mode to implicit painting thereafter:

    window.requestAnimationFrame(function(timestamp) {

      document.documentElement.paint();

      document.documentElement.paintPolicy = "implicit";

    });

  </script>


This leaves questions of what individual elements can do to paint
themselves unresolved, but something we should also investigate.

Thoughts?


> :DG<
>
>

Received on Wednesday, 27 November 2013 19:04:12 UTC