- From: John J Barton <johnjbarton@johnjbarton.com>
- Date: Wed, 27 Nov 2013 14:59:24 -0800
- To: Daniel Buchner <daniel@mozilla.com>
- Cc: Alex Russell <slightlyoff@google.com>, Dimitri Glazkov <dglazkov@google.com>, Ilya Grigorik <igrigorik@google.com>, Steven Souders <souders@google.com>, Brian Kardell <bkardell@gmail.com>, public-webapps <public-webapps@w3.org>, Erik Arvidsson <arv@chromium.org>, Scott Miles <sjmiles@google.com>
- Message-ID: <CAFAtnWzO03_zkC+8FqsHqmEz37fY3+QteXiM57amtytAU+N7vA@mail.gmail.com>
What if: <head> ... <link rel="import" href="elements/pi-app.html"> ... </head> <body> ... <pi-app theme="polymer-ui-light-theme"> <div class="app-loading"></div> </pi-app> ... was instead: <pi-app import="elements/pi-app.html" theme="polymer-ui-light-theme"> <div class="app-loading"></div> </pi-app> If I want to avoid FOUC, I precede this code with style that fill app-loading or that display:none pi-app, then pi-app.html changes the styles. If I want to block script on pi-app I use load events. If I want script to block pi-app loading, I put that script before pi-app. I'm just suggesting this, as a "dependency - driven" model where the dependency is attached directly to the dependent rather than floating up in <link>. This is similar to JS modules where the importer says "import", not .html saying <script>. (There are lots of HTML Import things that this may complicate, it's just a suggestion of another point of view). On Wed, Nov 27, 2013 at 12:32 PM, Daniel Buchner <daniel@mozilla.com> wrote: > JJB, this is precisely why the <paint> concept seemed like a good idea to > me: > > - Easy to use in just one or two places if needed, without a steep > cliff > - The choice shouldn't be: either put up with the browser's default > render flow, or become a low-level, imperative, perf hacker > - Enables load/render/paint tuning of both graphical and > non-visible, purely-functional elements > - Flexible enough to allow for complex cases, while being (relatively) > easy to grok for beginners > - Doesn't require devs to juggle a mix of declarative, top-level > settings, and imperative, per-element settings > > - Daniel > > On Wed, Nov 27, 2013 at 12:19 PM, John J Barton < > johnjbarton@johnjbarton.com> wrote: > >> I just can't help thinking this is whole line of reasoning all too >> complicated to achieve wide adoption and thus impact. >> >> The supposed power of declarative languages is ability to reason from top >> to bottom. Creating all of these exceptions causes the very problems being >> discussed: FOUC occurs because HTML Import runs async even though it looks >> like is it sync. Then we patch that up with eg "elements" and "paint". >> >> On the other hand, JS has allowed very sophisticated application loading >> to be implemented. If the async HTML Import were done with JS and if we >> added (if needed) rendering control support to JS, then we allow high >> function sites complete control of the loading sequence. >> >> I think we should be asking: "what can we do to have the best chance that >> most sites will show reasonable default content while loading on mobile >> networks?" A complex solution with confusing order of operations is fine >> for some sites, let them do it in JS. A declarative solution where default >> content appears before high-function content seems more likely to succeed >> for the rest. A complex declarative solution seems like the worst of both. >> HTH, >> jjb >> >> >> On Wed, Nov 27, 2013 at 11:50 AM, Daniel Buchner <daniel@mozilla.com>wrote: >> >>> Right on Dimitri, I couldn't agree more. It seems like an involved (but >>> highly beneficial) pursuit - but heck, maybe we'll find an answer quickly, >>> let's give it a shot! >>> >>> Alex, I completely agree that declarative features should play a huge >>> role in the solution, and I love the power/granularity you're alluding to >>> in your proposal. WARNING: the following may be completely >>> lol-batshit-crazy, so be nice! (remember, I'm not *really *a CS >>> person...I occasionally play one on TV). What if we created something like >>> this: >>> >>> <head> >>> <paint policy="blocking"> *// "non-blocking" would be the >>> default policy* >>> <link rel="import" href="first-load-components.html" /> >>> <script> >>> >>> *// Some script here** that is required for initial setup of or >>> interaction* >>> * // ** with the custom elements imported from >>> first-load-components.html* >>> >>> </script> >>> </paint> >>> </head> >>> >>> <body> >>> >>> <section> >>> *// content here is subject to default browser paint flow* >>> </section> >>> >>> <aside> >>> <paint framerate="5"> >>> >>> *// this content is essentially designated as low-priority, // but >>> framerate="5" could also be treated as a lower-bound target.* >>> </paint> >>> </aside> >>> >>> </body> >>> >>> >>> Here's what I intended in the example above: >>> >>> - A <paint> element would allow devs to easily, and explicitly, wrap >>> multiple elements with their own paint settings. *(you could go also >>> use attributes I suppose, but this way it is easy for someone new to the >>> code to Jump Right In™) * >>> - If there was a <paint> element, we could build-in a ton of >>> tunable, high-precision features that are easy to manipulate from all >>> contexts >>> >>> I'm going to duck now - I anticipate things will soon be thrown at me. >>> >>> - Daniel >>> >>> >>> On Wed, Nov 27, 2013 at 11:03 AM, Alex Russell <slightlyoff@google.com>wrote: >>> >>>> 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 22:59:51 UTC