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

I sent this to Scott only by accident, then noticed when I realized I need
to correct myself. First a softer version of my message to Scott:

On Mon, Nov 18, 2013 at 5:53 PM, Scott Miles <sjmiles@google.com> wrote:

> I believe the primary issue here is 'synchronous with respect to
> rendering'. Seems like you ignored this issue. See Brian's post.
>

Yes, I agree that issue should be discussed. Rendering synchrony makes a
strong case against Dimitri's proposal (now I switch my earlier
"not-competing" opinion). In my opinion, asynchronous component loading
driven by dependencies gives the best user experience and simplest dev
model. Second best is a synchronous model based on declaration order. Last
is an asynchronous "declarative" model (quote because such solutions are
not declarative).

I guess you would agree that the best user experience occurs after the web
components are loaded. So let's get there the fastest possible way: non
blocking asynchronous i/o.

After picking the fastest path, we get a bonus: we first render HTML5
content, anything our designers like: blank page, 'brought to you by ...',
etc. Thus we get control of the load-time UI.

The flash of unstyled content (FOUC) issue need not affect us because we
use web components with proper dependences rather than a pile-of-div-s plus
some independent JS.

The synchronous solution takes longer to load and shows browser defined
content in the meantime.

Therefore the dependency-driven asynchronous solution has better user
experience and a somewhat better dev model than declarative synchronous.

The declarative synchronous model has three important advantages: it is
simple to code, easy to reason about, and familiar. For the top- or
application-level on simple pages I think these advantages are important,
despite its failing in performance.

A "declarative" asynchronous solution (async attribute on link tag) can be
used to give the same user experience, but it loses on the development
model. It gives developers no help in load order and it creates confusion
by simulating imperative actions with declarative syntax.

FOUC is a sign of the failing of this kind of solution: the unstyled
content hits the rendering engine in the wrong order, before the JS that it
depends upon. If our dependency design is correct, we only deliver useful
content to the rendering engine.


> Scott
>
>
> On Mon, Nov 18, 2013 at 5:47 PM, John J Barton <
> johnjbarton@johnjbarton.com> wrote:
>
>>
>>
>>
>> On Mon, Nov 18, 2013 at 3:06 PM, Scott Miles <sjmiles@google.com> wrote:
>>
>>> >> I'll assert that the primary use case for JS interacting with HTML
>>> components ought to be 'works well with JS modules'.
>>>
>>> You can happily define modules in your imports, those two systems are
>>> friends as far as I can tell. I've said this before, I've yet to hear the
>>> counter argument.
>>>
>>
>> Yes indeed. Dimitri was asking for a better solution, but I agree that
>> both are feasible and compatible.
>>
>>
>>>
>>> >> But if you believe in modularity for Web Components then you should
>>> believe in modularity for JS
>>>
>>> Polymer team relies on Custom Elements for JS modularity. But again,
>>> this is not mutually exclusive with JS modules, so I don't see the problem.
>>>
>>
>> Steve's example concerns synchrony between <script> and <link
>> rel='import'>. It would be helpful if you can outline how your modularity
>> solution works for this case.
>>
>>
>>>
>>>
>>> >> Dimitri's proposal makes the async case much more difficult: you need
>>> both the link tag with async attribute then again you need to express the
>>> dependency with the clunky onload busines
>>>
>>> I believe you are making assumptions about the nature of link and async.
>>> There are ways of avoiding this problem,
>>>
>>
>> Yes I am assuming Steve's example, so again your version would be
>> interesting to see.
>>
>>
>>>  but it begs the question, which is: if we allow "Expressing the
>>> dependency in JS" then why doesn't 'async' (or 'sync') get us both what we
>>> want?
>>>
>>
>> I'm not arguing against any other solution that also works. I'm only
>> suggesting a solution that always synchronizes just those blocks of JS that
>> need order-of-execution and thus never needs 'sync' or 'async' and which
>> leads us to unify the module story for the Web.
>>
>> jjb
>>
>>
>>>
>>> Scott
>>>
>>> On Mon, Nov 18, 2013 at 2:58 PM, John J Barton <
>>> johnjbarton@johnjbarton.com> wrote:
>>>
>>>>
>>>>
>>>>
>>>> On Mon, Nov 18, 2013 at 2:33 PM, Scott Miles <sjmiles@google.com>wrote:
>>>>
>>>>> >> I love the idea of making HTML imports *not* block rendering as the
>>>>> default behavior
>>>>>
>>>>> So, for what it's worth, the Polymer team has the exact opposite
>>>>> desire. I of course acknowledge use cases where imports are being used to
>>>>> enhance existing pages, but the assertion that this is the primary use case
>>>>> is at least arguable.
>>>>>
>>>>
>>>> I'll assert that the primary use case for JS interacting with HTML
>>>> components ought to be 'works well with JS modules'. Today, in the current
>>>> state of HTML Import and JS modules, this sounds too hard. But if you
>>>> believe in modularity for Web Components then you should believe in
>>>> modularity for JS (or look at the Node ecosystem) and gee they ought to
>>>> work great together.
>>>>
>>>>
>>>>>
>>>>>
>>>>> >>  It would be the web dev's responsibility to confirm that the
>>>>> import was done loading
>>>>>
>>>>> Our use cases almost always rely on imports to make our pages sane.
>>>>> Requiring extra code to manage import readiness is a headache.
>>>>>
>>>>
>>>> I think your app would be overall even more sane if the dependencies
>>>> were expressed directly where they are needed. Rather than loading
>>>> components A,B,C,D then some JS that uses B,C,F, just load the JS and let
>>>> it pull B, C, F.  No more checking back to the list of <link> to compare to
>>>> the JS needs.
>>>>
>>>>
>>>>>
>>>>> Dimitri's proposal above tries to be inclusive to both world views,
>>>>> which I strongly support as both use-cases are valid.
>>>>>
>>>>
>>>> Dimitri's proposal makes the async case much more difficult: you need
>>>> both the link tag with async attribute then again you need to express the
>>>> dependency with the clunky onload business. Expressing the dependency in JS
>>>> avoids both of these issues.
>>>>
>>>> Just to point out: System.component()-ish need not be blocked by
>>>> completing ES module details and my arguments only apply for JS dependent
>>>> upon Web Components.
>>>>
>>>>
>>>>>
>>>>>
>>>>> Scott
>>>>>
>>>>> On Mon, Nov 18, 2013 at 2:25 PM, Steve Souders <souders@google.com>wrote:
>>>>>
>>>>>> I love the idea of making HTML imports *not* block rendering as the
>>>>>> default behavior. I believe this is what JJB is saying: make <link
>>>>>> rel=import> NOT block <script>.
>>>>>>
>>>>>> This is essential because most web pages are likely to have a SCRIPT
>>>>>> tag in the HEAD, thus the HTML import will block rendering of the entire
>>>>>> page. While this behavior is the same as stylesheets, it's likely to be
>>>>>> unexpected. Web devs know the stylesheet is needed for the entire page and
>>>>>> thus the blocking behavior is more intuitive. But HTML imports don't affect
>>>>>> the rest of the page - so the fact that an HTML import can block the entire
>>>>>> page the same way as stylesheets is likely to surprise folks. I don't have
>>>>>> data on this, but the reaction to my blog post reflects this surprise.
>>>>>>
>>>>>> Do we need to add a "sync" (aka "blockScriptFromExecuting")
>>>>>> attribute? I don't think so. It would be the web dev's responsibility to
>>>>>> confirm that the import was done loading before trying to insert it into
>>>>>> the document (using the "import ready flag"). Even better would be to train
>>>>>> web devs to use the LINK's onload handler for that.
>>>>>>
>>>>>> -Steve
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> On Mon, Nov 18, 2013 at 10:16 PM, John J Barton <
>>>>>> johnjbarton@johnjbarton.com> wrote:
>>>>>>
>>>>>>> Maybe Steve's example[1] could be on JS rather than on components:
>>>>>>>
>>>>>>> System.component("import.php", function(component) {
>>>>>>>   var content = component.content
>>>>>>>
>>>>>>> document.getElementById('import-container').appendChild(content.cloneNode(true));
>>>>>>> });
>>>>>>>
>>>>>>> Here we mimic System.load(jsId, success, error).  Then make <link>
>>>>>>> not block <script>: it's on JS to express the dependency correctly.
>>>>>>>
>>>>>>> jjb
>>>>>>>
>>>>>>>
>>>>>>> On Mon, Nov 18, 2013 at 1:40 PM, Dimitri Glazkov <
>>>>>>> dglazkov@google.com> wrote:
>>>>>>>
>>>>>>>> 'Sup yo!
>>>>>>>>
>>>>>>>> There was a thought-provoking post by Steve Souders [1] this
>>>>>>>> weekend that involved HTML Imports (yay!) and document.write (boo!), which
>>>>>>>> triggered a Twitter conversation [2], which triggered some conversations
>>>>>>>> with Arv and Alex, which finally erupted in this email.
>>>>>>>>
>>>>>>>> Today, HTML Imports loading behavior is very simply defined: they
>>>>>>>> act like stylesheets. They load asynchronously, but block <script> from
>>>>>>>> executing. Some peeps seem to frown on that and demand moar async.
>>>>>>>>
>>>>>>>> I am going to claim that there are two distinct uses of <link
>>>>>>>> rel=import>:
>>>>>>>>
>>>>>>>> 1) The import is the most important part of the document.
>>>>>>>> Typically, this is when the import is the underlying framework that powers
>>>>>>>> the app, and the app simply won't function without it. In this case, any
>>>>>>>> more async will be all burden and no benefit.
>>>>>>>>
>>>>>>>> 2) The import is the least important of the document. This is the
>>>>>>>> "+1 button" case. The import is useful, but sure as hell doesn't need to
>>>>>>>> take rendering engine's attention from presenting this document to the
>>>>>>>> user. In this case, async is sorely needed.
>>>>>>>>
>>>>>>>> We should address both of these cases, and we don't right now --
>>>>>>>> which is a problem.
>>>>>>>>
>>>>>>>> Shoot-from-the-hip Strawman:
>>>>>>>>
>>>>>>>> * The default behavior stays currently specified
>>>>>>>> * The "async" attribute on <link> makes import load asynchronously
>>>>>>>> * Also, consider not blocking rendering when blocking <script>
>>>>>>>>
>>>>>>>> This strawman is intentionally full of ... straw. Please provide a
>>>>>>>> better strawman below:
>>>>>>>> __________________
>>>>>>>> __________________
>>>>>>>> __________________
>>>>>>>>
>>>>>>>> :DG<
>>>>>>>>
>>>>>>>> [1]:
>>>>>>>> http://www.stevesouders.com/blog/2013/11/16/async-ads-with-html-imports/
>>>>>>>> [2]: https://twitter.com/codepo8/status/401752453944590336
>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>
>>>>>
>>>>
>>>
>>
>

Received on Wednesday, 20 November 2013 00:26:27 UTC