Re: [whatwg] Script preloading

2013-10-02 Thread Bruno Racineux


On 8/27/13 2:55 PM, Ian Hickson i...@hixie.ch wrote:


First, let's get down to use cases. Kyle did a great job of describing
some key use cases:

On Wed, 10 Jul 2013, Kyle Simpson wrote:

 [Use-case Q:] I am dynamically loading one of those social widgets
that, 
 upon load, automatically scans a page and renders social buttons. I
need 
 to be able to preload that script so it's ready to execute, but decide
 when I want it to run against the page. I don't want to wait for true
 on-demand loading, like when my user clicks a button, because of the
 loading delay that will be visible to the user, so I want to pre-load
 that script and have it waiting, ready at a moment's notice to say
it's 
 ok to execute, do it now! now! now!.

 [Use-case S:] One CMS plugin wants to load A.js and B.js, where B
 relies on A. Both need to load in parallel (for performance), but A
must 
 execute before B executes. I don't control A and B, so changing them is
 not an option. This CMS plugin [wants] to wait for some
 user-interaction, such as a button click, before executing the code. We
 don't want there to be any big network-loading delay visible to the
user 
 between their click of the button and the running of that plugin's code.
 
 Another CMS plugin on this same page wants to load A.js, C.js, and
 D.js. This plugin doesn't know or care that the other plugin also
 requests A.js. It doesn't know if there is a script element in the
 page requesting it or not, and it doesn't want to looking for it. It
 just wants to ask for A as a pre-requisite to C and D. But C and D have
 no dependency on each other, only a shared dependency on A. C and D
 should be free to run ASAP (in whichever order), assuming that A has
 already run [once] some user-interaction that initiates the load of A,
 C, and D. This user interaction may be before the other plugin
requested 
 A, or after it requested A.

 A.js can be requested relatively (via a base tag or just relative
to 
 document root) or absolutely, or it might be requested with the
 leading-// protocol-relative from, taking on whatever http or https
 protocol the page has, whereas other references to it may specify the
 prototcol.

 These plugins can't guarantee what ID's or classes they use are
reliably 
 unique without undue processing burden.

[I've trimmed the text Kyle wrote here, but also implicit in his
description, as I understood it, was that A.js should only run once even
if both plugins tried to load it.]

 [Use-case T:] I have two different calendar widgets. I want to pop one
 of them up when a user clicks a button. The user may never click the
 button, in which case I don't want the calendar widget to have ever
 executed to render. [...]
 
 It'd be nice if both calendar widgets were built sensibly so that
 loading the code didn't automatically render. One of them IS, the other
 is unfortunately mis-behaving, and it will render itself as soon as its
 code is run. [...]
 
 Furthermore, these two widgets are not equal. Perhaps one is better
 for smaller browser window sizes, and the other is better for larger
 browser windows. [...]
 
 Regardless, the point is, there's run-time conditions which are going
to 
 determine if I want to execute calendar widget A or B, or maybe I never
 execute either. But I want them both preloaded and ready to go, just in
 case, so that if the user DOES need one, it's free and ready to execute
 with nearly no delay, instead of having to wait to request as I would
 with only on-demand techniques.

 [Use-case U:] I have a set of script A.js, B.js, and C.js. B
 relies on A, and C relies on B. So they need to execute strictly in
that 
 order. [Now], imagine they progressively render different parts of a
 widget. [...] I only want to execute A, B and C once all 3 are
preloaded 
 and ready to go. It's [...] about minimizing delays between them, for
 performance PERCEPTION.

 [For example, one of them might start playing a video, and another
might 
 introduce the canvas slides for that video. You want all of the
 relevant scripts to be run at once, so there's no point where the page
 has a video element but doesn't have the canvas.]

On Thu, 11 Jul 2013, Kyle Simpson wrote:
 
 [Use-case V:] you have a string of scripts (A.js, B.js, and C.js)
 loading which constitute a dependency chain. A must run before B, which
 must run before C. However, if you detect an error in loading, you stop
 the rest of the executions (and preferably loading too!), since clearly
 dependencies will fail for further scripts, and the errors will just
 unnecessarily clutter the developer console log making it harder to
 debug.

 [Use-case W:] some developers have even requested to be able to stop
the 
 chain and prevent further executions if the script loads, but there's
 some compile-time syntax error or run-time error that happens during
the 
 execution. For them, it's not enough for B to simply finish loading
 successfully, but that it must fully execute without error.

On Sun, 14 

Re: [whatwg] Script preloading

2013-09-03 Thread Jake Archibald
On 31 August 2013 00:04, Ryosuke Niwa rn...@apple.com wrote:

 It'll be much harder to implement a new dependency API that replies on CSS
 selectors if we care about the performance at all.


Where does the performance issue come from? It would only need to be
resolved once on node creation or insertion into the document (the latter
of the two). It's only used for execution, downloads can still be triggered
without resolving the selectors (eg, by a pre-scanner).


Re: [whatwg] Script preloading

2013-09-03 Thread Boris Zbarsky

On 9/3/13 2:27 PM, Ryosuke Niwa wrote:

 From the fact selector matching is slow.


Hold on.  Back up.

Selector matching can't be all that slow per se: browsers do it a 
_lot_.  Do you mean doing the equivalent of document.querySelectorAll 
can be slow?


-Boris


Re: [whatwg] Script preloading

2013-09-03 Thread Ryosuke Niwa
Original proposal:
http://lists.whatwg.org/pipermail/whatwg-whatwg.org/2013-August/040664.html
http://lists.whatwg.org/pipermail/whatwg-whatwg.org/2013-August/040666.html

In order to address use cases incDependencies and decDependencies satisfied, 
I'm going to add the following proposals:

I make one more change that in order for a dependency specified in needs to 
be satisfied,
src content attribute of the dependent script needs to match the value when 
the script finished running.
e.g. myscript.src = null leaves any dependency on myscript unsatisfied.

Also make needs IDL property take in any HTML element; e.g. adding an image 
element to needs makes the script wait until the corresponding image resource 
is loaded.

On Aug 27, 2013, at 2:55 PM, Ian Hickson i...@hixie.ch wrote:

 
 First, let's get down to use cases. Kyle did a great job of describing 
 some key use cases:
 
 On Wed, 10 Jul 2013, Kyle Simpson wrote:
 
 [Use-case Q:] I am dynamically loading one of those social widgets that, 
 upon load, automatically scans a page and renders social buttons. I need 
 to be able to preload that script so it's ready to execute, but decide 
 when I want it to run against the page. I don't want to wait for true 
 on-demand loading, like when my user clicks a button, because of the 
 loading delay that will be visible to the user, so I want to pre-load 
 that script and have it waiting, ready at a moment's notice to say it's 
 ok to execute, do it now! now! now!.

script id=social src=social-button.js prefetch/script
button onmouseover=document.scripts.social.execute() ... /button

 [Use-case S:] One CMS plugin wants to load A.js and B.js, where B 
 relies on A. Both need to load in parallel (for performance), but A must 
 execute before B executes. I don't control A and B, so changing them is 
 not an option. This CMS plugin [wants] to wait for some 
 user-interaction, such as a button click, before executing the code. We 
 don't want there to be any big network-loading delay visible to the user 
 between their click of the button and the running of that plugin's code.

// CMS plugin 1
var A = E('script', { src: 'A.js', prefetch: true });
var B = E('script', { src: 'B.js', needs: 'A.js', prefetch: true });
document.body.append(A, B);
function sawUserInteraction() {
  B.execute();
};


 Another CMS plugin on this same page wants to load A.js, C.js, and 
 D.js. This plugin doesn't know or care that the other plugin also 
 requests A.js. It doesn't know if there is a script element in the 
 page requesting it or not, and it doesn't want to looking for it. It 
 just wants to ask for A as a pre-requisite to C and D. But C and D have 
 no dependency on each other, only a shared dependency on A. C and D 
 should be free to run ASAP (in whichever order), assuming that A has 
 already run [once] some user-interaction that initiates the load of A, 
 C, and D. This user interaction may be before the other plugin requested 
 A, or after it requested A.

// CMS plugin 2
var A = E('script', { src: 'A.js', prefetch: true });
var C = E('script', { src: 'C.js', needs: 'A.js', prefetch: true });
var D = E('script', { src: 'D.js', needs: 'A.js', prefetch: true });
document.body.append(A, C, D);
function sawUserInteraction() {
  C.execute();
  D.execute();
};

 A.js can be requested relatively (via a base tag or just relative to 
 document root) or absolutely, or it might be requested with the 
 leading-// protocol-relative from, taking on whatever http or https 
 protocol the page has, whereas other references to it may specify the 
 prototcol.
 
 These plugins can't guarantee what ID's or classes they use are reliably 
 unique without undue processing burden.
 
 [I've trimmed the text Kyle wrote here, but also implicit in his 
 description, as I understood it, was that A.js should only run once even 
 if both plugins tried to load it.]
 
 [Use-case T:] I have two different calendar widgets. I want to pop one 
 of them up when a user clicks a button. The user may never click the 
 button, in which case I don't want the calendar widget to have ever 
 executed to render. [...]

script id=calA src=a.js prefetch/script
script id=calB src=b.js prefetch/script
script
function showCalendar(which) {
 if (which == 'a')
   document.scripts.calA.execute();
 else
   document.scripts.calB.execute();
}
/script

Neither Ian's nor my proposal fallbacks gracefully here :(

 [Use-case U:] I have a set of script A.js, B.js, and C.js. B 
 relies on A, and C relies on B. So they need to execute strictly in that 
 order. [Now], imagine they progressively render different parts of a 
 widget. [...] I only want to execute A, B and C once all 3 are preloaded 
 and ready to go. It's [...] about minimizing delays between them, for 
 performance PERCEPTION.
 
 [For example, one of them might start playing a video, and another might 
 introduce the canvas slides for that video. You want all of the 
 relevant scripts to be run at once, so there's no 

Re: [whatwg] Script preloading

2013-09-03 Thread Ryosuke Niwa
On Sep 3, 2013, at 3:45 AM, Jake Archibald jaffathec...@gmail.com wrote:

 On 31 August 2013 00:04, Ryosuke Niwa rn...@apple.com wrote:
 
 It'll be much harder to implement a new dependency API that replies on CSS
 selectors if we care about the performance at all.
 
 
 Where does the performance issue come from? It would only need to be
 resolved once on node creation or insertion into the document (the latter
 of the two). It's only used for execution, downloads can still be triggered
 without resolving the selectors (eg, by a pre-scanner).


From the fact selector matching is slow.  I'm opposed to adding selector 
dependency unless there is a very important use case that can't be addressed 
by referring to a script by an element id or a script filename.

- R. Niwa



Re: [whatwg] Script preloading

2013-09-03 Thread Ryosuke Niwa
Per IRC discussion, I misunderstood the timing at which these at which 
dependencies are executed.  Now I agree it's desirable to have two values for 
when needed as proposed by Ian in the original e-mail.

For other people following this thread's sake, a.js will execute immediately as 
soon as it's loaded in this example:
script src=a.js whenneeded/script
script id=b src=b.js needs=a.js whendeeded/script
// later
document.scripts.b.execute();

whereas a.js doesn't get executed until b.js is loaded in this example:
script src=a.js whenneeded=jit/script
script id=b src=b.js needs=a.js whendeeded/script
// later
document.scripts.b.execute();

- R. Niwa

On Sep 3, 2013, at 2:49 PM, Ryosuke Niwa rn...@apple.com wrote:

 Original proposal:
 http://lists.whatwg.org/pipermail/whatwg-whatwg.org/2013-August/040664.html
 http://lists.whatwg.org/pipermail/whatwg-whatwg.org/2013-August/040666.html
 
 In order to address use cases incDependencies and decDependencies satisfied, 
 I'm going to add the following proposals:
 
 I make one more change that in order for a dependency specified in needs to 
 be satisfied,
 src content attribute of the dependent script needs to match the value when 
 the script finished running.
 e.g. myscript.src = null leaves any dependency on myscript unsatisfied.
 
 Also make needs IDL property take in any HTML element; e.g. adding an image 
 element to needs makes the script wait until the corresponding image 
 resource is loaded.
 
 On Aug 27, 2013, at 2:55 PM, Ian Hickson i...@hixie.ch wrote:
 
 
 First, let's get down to use cases. Kyle did a great job of describing 
 some key use cases:
 
 On Wed, 10 Jul 2013, Kyle Simpson wrote:
 
 [Use-case Q:] I am dynamically loading one of those social widgets that, 
 upon load, automatically scans a page and renders social buttons. I need 
 to be able to preload that script so it's ready to execute, but decide 
 when I want it to run against the page. I don't want to wait for true 
 on-demand loading, like when my user clicks a button, because of the 
 loading delay that will be visible to the user, so I want to pre-load 
 that script and have it waiting, ready at a moment's notice to say it's 
 ok to execute, do it now! now! now!.
 
 script id=social src=social-button.js prefetch/script
 button onmouseover=document.scripts.social.execute() ... /button
 
 [Use-case S:] One CMS plugin wants to load A.js and B.js, where B 
 relies on A. Both need to load in parallel (for performance), but A must 
 execute before B executes. I don't control A and B, so changing them is 
 not an option. This CMS plugin [wants] to wait for some 
 user-interaction, such as a button click, before executing the code. We 
 don't want there to be any big network-loading delay visible to the user 
 between their click of the button and the running of that plugin's code.
 
 // CMS plugin 1
 var A = E('script', { src: 'A.js', prefetch: true });
 var B = E('script', { src: 'B.js', needs: 'A.js', prefetch: true });
 document.body.append(A, B);
 function sawUserInteraction() {
  B.execute();
 };
 
 
 Another CMS plugin on this same page wants to load A.js, C.js, and 
 D.js. This plugin doesn't know or care that the other plugin also 
 requests A.js. It doesn't know if there is a script element in the 
 page requesting it or not, and it doesn't want to looking for it. It 
 just wants to ask for A as a pre-requisite to C and D. But C and D have 
 no dependency on each other, only a shared dependency on A. C and D 
 should be free to run ASAP (in whichever order), assuming that A has 
 already run [once] some user-interaction that initiates the load of A, 
 C, and D. This user interaction may be before the other plugin requested 
 A, or after it requested A.
 
 // CMS plugin 2
 var A = E('script', { src: 'A.js', prefetch: true });
 var C = E('script', { src: 'C.js', needs: 'A.js', prefetch: true });
 var D = E('script', { src: 'D.js', needs: 'A.js', prefetch: true });
 document.body.append(A, C, D);
 function sawUserInteraction() {
  C.execute();
  D.execute();
 };
 
 A.js can be requested relatively (via a base tag or just relative to 
 document root) or absolutely, or it might be requested with the 
 leading-// protocol-relative from, taking on whatever http or https 
 protocol the page has, whereas other references to it may specify the 
 prototcol.
 
 These plugins can't guarantee what ID's or classes they use are reliably 
 unique without undue processing burden.
 
 [I've trimmed the text Kyle wrote here, but also implicit in his 
 description, as I understood it, was that A.js should only run once even 
 if both plugins tried to load it.]
 
 [Use-case T:] I have two different calendar widgets. I want to pop one 
 of them up when a user clicks a button. The user may never click the 
 button, in which case I don't want the calendar widget to have ever 
 executed to render. [...]
 
 script id=calA src=a.js prefetch/script
 script id=calB src=b.js prefetch/script
 script
 

Re: [whatwg] Script preloading

2013-09-03 Thread 陈智昌
Hello folks. Sorry for the late response to several comments in this
mega-thread, I've mostly been traveling/vacationing for the past 2 months.
A teammate asked me to look at this in case I had comments. I don't know
web dev issues very well, so I'm going to restrain myself from offering
many opinions about the new proposals other than wow, all this dependency
stuff looks complicated, but maybe it's worth it? I'll keep to some
observations from a networking performance perspective, in case it's
relevant to the discussion:

* Any advantages the preloader currently gives is probably only going to be
magnified with HTTP/2. Browsers today will in key situations hold back
lower priority resource loads, even after the resource has been discovered
by the parser/preloader, in order to reduce network contention and
prioritize resources. But with HTTP/2, the browser almost never has to do
this since it can express the request priority in the HTTP/2 protocol
itself, and let the server order responses appropriately.
* link rel=subresource is great for resource discovery. Given the above
observation, note that it has some deficiencies. Most obviously, it does
not indicate the resource type. Browsers today can heuristically assign a
priority based on the resource type (script/image/stylesheet/etc).
Arguably, browsers could just use the filename extension as a hint to the
resource type, and that'd get us most of the way there. In any case,
Chromium, when it encounters link rel=subresource is going to assign the
resource load the lowest priority level, and only when the parser
encounters the actual resource via a script tag or something, will
another resource load be issued with the appropriate priority. Almost all
modern browsers will hold back low priority resource loads before first
paint in order to get critical scripts and stylesheets in head ASAP
without contention. Anything marked with link rel=subresource will be
considered low priority and in all likelihood not requested early. Note
that HTTP/2 currently does not support re-prioritization (and that feature
is being debated), so that means that when the resource load for link
rel=subresource gets issued over an HTTP/2 connection, it will have the
lowest priority, which is probably undesirable. FWIW, I think link
rel=subresource was a good initial start, but suffers from key weaknesses
and should be thrown out and replaced.
* Given current browser heuristics for resource prioritization based on
resource type, all script resources will have the same priority. Within
HTTP/1.X, that means you'll get some amount of parallelization based on the
connection per host limit and what origins the script resources are hosted,
and then get FIFO. New additions like lazyload attributes (and perhaps
leveraging the defer attribute) may affect this. With HTTP/2, there is a
very high (effectively infinite) parallelization limit. With
prioritization, there's no contention across priority levels. But since
script resources today generally all have the same priority, they will all
contend and most naive servers are going to round robin the response bytes,
which is the worst thing you could do with script resources, since current
JS VMs do not incrementally process script resources, but process them as a
whole. So round-robining all the response bytes will just push out start
time of JS processing for all scripts, which is rather terrible.
* Obviously, given what I've said above, some level of hinting of
prioritization/dependency amongst scripts/resources within the web platform
would be useful to the networking layer since the networking layer can much
more effectively prioritize resources and thus mitigate network contention.
If finer grained priority/dependency information isn't provided in the web
platform, my browser's networking stack is likely going to have to, even
with HTTP/2, do HTTP/1.X style contention mitigation by restricting
parallelization within a priority level. Which is a shame since web
developers probably think that with HTTP/2, they can have as many fine
grained resources as they want.

Cheers.


On Wed, Jul 10, 2013 at 3:39 AM, Ian Hickson i...@hixie.ch wrote:


 A topic that regularly comes up is script loading.

 I sent an e-mail responding to related feedback last year, though it
 didn't get any replies to the script loading parts of it:


 http://lists.w3.org/Archives/Public/public-whatwg-archive/2012Dec/0221.html

 It seems that people want something that:

  - Lets them download scripts but not execute them until needed.
  - Lets them have multiple interdependent scripts and have the browser
manage their ordering.
  - Do all this without having to modify existing scripts.

 I must admit to not really understanding these requirements (script
 execution can be made more or less free if they are designed to just
 expose some functions, for example, and it's trivial to set up a script
 dependency mechanism for scripts to run each other in order, and there's
 

Re: [whatwg] Script preloading

2013-08-30 Thread Yoav Weiss
On Tue, Aug 27, 2013 at 11:55 PM, Ian Hickson i...@hixie.ch wrote:



 On Thu, 11 Jul 2013, Yoav Weiss wrote:
 
  I've recently contemplated the slightly related issue of adding the
  media attribute to script, for declarative loading of scripts that
  are only relevant to some viewports [1] While it may complicate certain
  things (e.g. execution when media conditions change, dependencies), I
  believe it's worth while to give it some thought, as it'd enable
  preloaders to fetch these scripts as soon as possible, in case they are
  needed.

 How common are media-specific scripts?


They are fairly common, especially for loading of mobile UI components
(e.g. jquery mobile). They can also be used to download dynamic page
components (e.g. maps) only on larger devices.
But, unless adding `media` to script elements is relatively simple, I think
that this use-case can be resolved by using the media attribute on rel
subresource, in combination with ES6 modules or a custom script loader. As
far as I understand it, all link elements can have a media attribute [1],
so this is simply an implementation issue.

[1]
http://www.whatwg.org/specs/web-apps/current-work/multipage/semantics.html#the-link-element


Re: [whatwg] Script preloading

2013-08-30 Thread Ryosuke Niwa

On Aug 30, 2013, at 9:08 AM, Yoav Weiss y...@yoav.ws wrote:

 On Tue, Aug 27, 2013 at 11:55 PM, Ian Hickson i...@hixie.ch wrote:
 
 On Thu, 11 Jul 2013, Yoav Weiss wrote:
 
 I've recently contemplated the slightly related issue of adding the
 media attribute to script, for declarative loading of scripts that
 are only relevant to some viewports [1] While it may complicate certain
 things (e.g. execution when media conditions change, dependencies), I
 believe it's worth while to give it some thought, as it'd enable
 preloaders to fetch these scripts as soon as possible, in case they are
 needed.
 
 How common are media-specific scripts?
 
 
 They are fairly common, especially for loading of mobile UI components
 (e.g. jquery mobile). They can also be used to download dynamic page
 components (e.g. maps) only on larger devices.
 But, unless adding `media` to script elements is relatively simple, I think
 that this use-case can be resolved by using the media attribute on rel
 subresource, in combination with ES6 modules or a custom script loader. As
 far as I understand it, all link elements can have a media attribute [1],
 so this is simply an implementation issue.

I don't think it'll be hard to add the media attribute on the script element at 
least in WebKit.

It'll be much harder to implement a new dependency API that replies on CSS 
selectors if we care about the performance at all.

- R. Niwa



Re: [whatwg] Script preloading

2013-08-30 Thread Garrett Smith
On 8/30/13, Ryosuke Niwa rn...@apple.com wrote:

 On Aug 30, 2013, at 9:08 AM, Yoav Weiss y...@yoav.ws wrote:

 On Tue, Aug 27, 2013 at 11:55 PM, Ian Hickson i...@hixie.ch wrote:

 On Thu, 11 Jul 2013, Yoav Weiss wrote:

[...]


 They are fairly common, especially for loading of mobile UI components
 (e.g. jquery mobile). They can also be used to download dynamic page
 components (e.g. maps) only on larger devices.
 But, unless adding `media` to script elements is relatively simple, I
 think
 that this use-case can be resolved by using the media attribute on rel
 subresource, in combination with ES6 modules or a custom script loader.
 As
 far as I understand it, all link elements can have a media attribute
 [1],
 so this is simply an implementation issue.

 I don't think it'll be hard to add the media attribute on the script element
 at least in WebKit.

 It'll be much harder to implement a new dependency API that replies on CSS
 selectors if we care about the performance at all.

What is this in response to? What dependency API that relies on CSS
selectors? (I'm assuming you mean relies and not replies, but still
not sure what you mean).
-- 
Garrett
Twitter: @xkit
personx.tumblr.com


Re: [whatwg] Script preloading

2013-08-30 Thread Ryosuke Niwa
On Aug 30, 2013, at 4:36 PM, Garrett Smith dhtmlkitc...@gmail.com wrote:

 On 8/30/13, Ryosuke Niwa rn...@apple.com wrote:
 
 I don't think it'll be hard to add the media attribute on the script element
 at least in WebKit.
 
 It'll be much harder to implement a new dependency API that replies on CSS
 selectors if we care about the performance at all.
 
 What is this in response to? What dependency API that relies on CSS
 selectors? (I'm assuming you mean relies and not replies, but still
 not sure what you mean).

Sorry, I meant to say relies.  I was referring to the Jake's version of the 
dependency resolution mechanism as seen below:

On Aug 29, 2013, at 9:42 AM, Jake Archibald jaffathec...@gmail.com wrote:
 I'm not sure it's possible to get into loops with this. I imagined
 dependency resolution to happen once, on element creation or adding to
 document (whichever happens latest). So with:
 
 script src=a.js needs=script[src=b.js]/script
 script src=b.js needs=script[src=a.js]/script
 
 …the first script would have zero dependencies, because the selector
 matches zero elements. The second would depend on the first, so the
 execution order is a.js, b.js. The thing I like about the selector thing is
 you can very easily get (almost) async=false behaviour:



Going back to Ian's proposal.

On Aug 27, 2013, at 2:55 PM, Ian Hickson i...@hixie.ch wrote:
 Here's a proposal that attempts to address all the use cases:
 
 High-level overview:
 
  script elements get a new whenneeded= attribute, which delays the 
  execution of the script until the script element's execute() method is 
  called. (This essentially provides the same as the preload 
  suggestions.)
 
  script elements also get a new needs= attribute, which takes a list 
  of URLs. A script won't run (even if you call execute()) until all the 
  script src= elements referenced by its needs= attribute are 
  themselves ready to run. For example:
 
 script src=b.js needs=a.js/script
 script src=a.js async/script
 
 ...will execute a.js when it's ready, and only then execute b.js. needs 
 basically implies async if its needs aren't met when it first tries to run.
 
 script whenneeded=jit is a special mode where instead of running once 
 the script's dependencies are met, it additionally waits until all the 
 scripts that depend on _it_ are ready to run. (Just in time exection.) 
 (The default is whenneeded=asap, as soon as possible exection.)
 
 You can manually increase or decrease a dependency count on script 
 elements by calling incDependencies() and decDependencies().
 
 
 Details (tersely):
 
  scripts have a whenneeded mode, initially none, can also be asap, 
 jit.

I don't quite understand why we need two values for whenneded.

Why can't we simply have prefetch (since we already use that term in the link 
element) and needs (I'd prefer calling it requires) content attributes?

When a script element has the prefetch attribute, it doesn't execute until 
execute() is called upon the element unless
(i.e. the script is executed immediately when the script has been loaded) if at 
least one of its dependencies is not a prefetch
(i.e. doesn't have the prefetch content attribute).

Could you clarify which use case this alternative proposal doesn't address?

  script gets a method, execute():
0. mark as needed
0. call execute() on each script we depend on  
0. if we didn't depend on any, check if we need to run
 
  script gets a pair of methods, incDependencies() and decDependencies(), 
  that increase and decrease the dependency count by one, respectively
  decDependencies() throws if called when the count is zero. If 
  decDependencies() is called and it reduces the number to zero,

I strongly oppose to adding incDependencies/decDependencies.  We try not to add 
those pairwise functions as much as possible our C++ code because it's really 
hard to always pair function calls.

- R. Niwa



Re: [whatwg] Script preloading

2013-08-30 Thread Glenn Maynard
I don't like the name jit, because it already has a different meaning
when talking about scripting.  If this was for CSS or WebVTT or something
else other than scripts, it wouldn't be as bad...

On Fri, Aug 30, 2013 at 7:22 PM, Ryosuke Niwa rn...@apple.com wrote:

  I don't quite understand why we need two values for whenneded.

 Why can't we simply have prefetch (since we already use that term in the
 link element) and needs (I'd prefer calling it requires) content
 attributes?

 When a script element has the prefetch attribute, it doesn't execute until
 execute() is called upon the element unless
 (i.e. the script is executed immediately when the script has been loaded)
 if at least one of its dependencies is not a prefetch
 (i.e. doesn't have the prefetch content attribute).


I'm not sure what you mean (skipping the parenthetical this says unless
if, so I'm not sure how to parse that), but prefetch sounds like
something different than jit.

prefetch sounds like a hint about networking behavior, eg. download this
script, even if it isn't needed yet.  On the other hand, jit changes
when the script is executed, not when it's downloaded: it means don't
execute the script's contents until the scripts that depend on this one are
also ready to be downloaded.

Could you clarify which use case this alternative proposal doesn't address?


The use case was download several scripts, then execute them all at
once.  I'm not sure about that use case, but a prefetch hint doesn't seem
right for that.  You'd end up downloading the scripts even if they're never
used.  With jit, the browser can still avoid downloading the scripts
entirely if they're not used.

-- 
Glenn Maynard


Re: [whatwg] Script preloading

2013-08-30 Thread Ryosuke Niwa

On Aug 30, 2013, at 5:54 PM, Glenn Maynard gl...@zewt.org wrote:

 I don't like the name jit, because it already has a different meaning when 
 talking about scripting.  If this was for CSS or WebVTT or something else 
 other than scripts, it wouldn't be as bad...
 
 On Fri, Aug 30, 2013 at 7:22 PM, Ryosuke Niwa rn...@apple.com wrote:
 I don't quite understand why we need two values for whenneded.
 
 Why can't we simply have prefetch (since we already use that term in the 
 link element) and needs (I'd prefer calling it requires) content 
 attributes?
 
 When a script element has the prefetch attribute, it doesn't execute until 
 execute() is called upon the element unless
 (i.e. the script is executed immediately when the script has been loaded) if 
 at least one of its dependencies is not a prefetch
 (i.e. doesn't have the prefetch content attribute).
 
 I'm not sure what you mean (skipping the parenthetical this says unless if, 
 so I'm not sure how to parse that), but prefetch sounds like something 
 different than jit.

Yes.  Prefetch is like noexecute if there are no dependencies that require 
immediate execution.  But it behaves like jit if there are dependencies.

Example 1.
script src=A.js prefetch/script
script src=B.js requires=C.js prefetch/script
script src=C.js prefetch/script
Neither A.js, B.js, nor C.js are executed until execute() is called on each 
element.

Example 2.
script src=A.js prefetch/script
script src=B.js requires=C.js/script
script src=C.js prefetch/script
Both C.js and B.js are executed respectively once they're loaded since C.js 
requires B.js.

Example 2.
script src=A.js prefetch/script
script src=B.js requires=C.js/script
script src=C.js requires=A.js prefetch/script
A.js, C.js, B.js are executed respectively because B.js requires C.js that 
in turn requires A.js

 The use case was download several scripts, then execute them all at once.  
 I'm not sure about that use case, but a prefetch hint doesn't seem right for 
 that.  You'd end up downloading the scripts even if they're never used.

There was a use case for fetching a script without ever executing them until 
execute() is called.

I'll argue, however, that UAs should have the option NOT to fetch such a script 
immediately based on the network condition, bandwidth, etc...  That's why I 
like the name prefetch because it implies a weak requirement.

Another problem I'm interested in hearing Web developer's opinion is how we can 
manage the priority of resource requests.  e.g. scripts only used for some 
obscure feature on a page can be requested later;  Web browser should be able 
to prioritize requests for the page's main assets such as the tile image, web 
fonts, etc...

- R. Niwa



Re: [whatwg] Script preloading

2013-08-29 Thread Brian Kardell
On Aug 29, 2013 1:21 AM, Jonas Sicking jo...@sicking.cc wrote:

 Hi Ryosuke,

 Based on the feedback here, it doesn't sound like you are a huge fan
 of the original proposal in this thread.

 At this point, has any implementation come out in support of the
 proposal in this thread as a preferred solution over
 noexecute/execute()?

 The strongest support I've seen in this thread, though I very well
 could have missed some, is it's better than status quo.

 Is that the case?

 / Jonas

 On Wed, Aug 28, 2013 at 7:43 PM, Ryosuke Niwa rn...@apple.com wrote:
  On Jul 13, 2013, at 5:55 AM, Andy Davies dajdav...@gmail.com wrote:
 
  On 12 July 2013 01:25, Bruno Racineux br...@hexanet.net wrote:
 
  On browser preloading:
 
  There seems to an inherent conflict between 'indiscriminate'
Pre-parsers/
  PreloadScanner and responsive design for mobile. Responsive designs
  mostly implies that everything needed for a full screen desktop is
  provided in markup to all devices.
 
 
  The pre-loader is a tradeoff, it's aiming to increase network
utilisation
  by speculatively downloading resources it can discover.
 
  Some of the resources downloaded may be not be used but with good
design
  and mobile first approaches hopefully this number can be minimised.
 
  Even if some unused resources get downloaded how much it matter?
 
  It matters a lot when you only have GSM wireless connection, and barely
loading anything at all.
 
  By starting the downloads earlier, connections will be opened sooner,
and
  the TCP congestion window to grow sooner. Of course this has to be
balanced
  against visitors who might be paying to download those unused bytes,
and
  whether the unused resources are blocking something on the critical
path
  from being downloaded (believe some preloaders can re-prioritise
resources
  if they need them before the preloader has downloaded them)
 
  Exactly.  I'd to make sure whatever API we come up gives enough
flexibility for the UAs to decide whether a given resource needs to be
loaded immediatley.
 
 
 
  On Jul 12, 2013, at 11:56 AM, Kyle Simpson get...@gmail.com wrote:
 
  My scope (as it always has been) put simply: I want (for all the
reasons here and before) to have a silver bullet in script loading, which
lets me load any number of scripts in parallel, and to the extent that is
reasonable, be fully in control of what order they run in, if at all,
responding to conditions AS THE SCRIPTS EXECUTE, not merely as they might
have existed at the time of initial request. I want such a facility because
I want to continue to have LABjs be a best-in-class fully-capable script
loader that sets the standard for best-practice on-demand script loading.
 
 
  Because of the different network conditions and constraints various
devices have, I'm wary of any solution that gives the full control over
when each script is loaded.  While I'm sure large corporations with lots of
resources will get this right, I don't want to provide a preloading API
that's hard to use for ordinary Web developers.
 
 
  On Jul 15, 2013, at 7:55 AM, Kornel Lesiński kor...@geekhood.net
wrote:
 
  There's a very high overlap between module dependencies and script
dependencies proposal. I think at very least it would be useful to define
script dependencies in terms of ES6 modules, or even abandon markup
solution to avoid duplicating features.
 
  ES6 modules however do not solve the performance problem. In fact they
would benefit from UA having a list of all dependencies up front (otherwise
file's dependencies can only be discovered after that file is loaded, which
costs as many RTTs as the height of the dependency tree).
 
  So I think that eventually ES6 modules + link[rel=subresource] could
be the answer. The link would expose URLs to (pre)load for performance,
but modules would handle actual loading/execution for flexibility and
reliability.
 
 
  Yes, we should definitely consider how this preloading API works with
ES6 modules.
 
 
 
  On Jul 22, 2013, at 3:22 PM, Jonas Sicking jo...@sicking.cc wrote:
 
  Having the load event anytime we are done with a network request also
  seems beneficial. Rather than having most APIs use load whereas this
  would use preload.
 
  Generally speaking load means loaded and processed. The
  'noexecute' flag would change what the and processed piece includes.
 
  I don't think it'll be confusing if the script had noexecute.  We can
even call it noautoexecute if we wanted.
 
  But I'm fine either way here. The same question and risk of confusion
  seems to exist with the whenneeded attribute. In general
  whenneeded seems very similar to noexecute, but with a little bit
  more stuff done automatically, for better or worse.
 
  I like the simplicity of noexecute and excute().  However, I'm a little
worried that it doesn't provide any information as to how important a given
script is.  So Web browsers have no choice but to request all scripts
immediately.
 
  I'd like to eventually provide APIs that allow 

Re: [whatwg] Script preloading

2013-08-29 Thread Nicholas Zakas
When Kyle and I originally started pushing for a way to preload JavaScript
many moons ago, the intent was very simple: to allow the downloading of
JavaScript and execution of JavaScript to be separate. The idea being that
you should be able to preload scripts that you'll need later without
incurring the cost of parsing and execution at that point in time. There
are many examples of people doing this, the most famous being the Gmail
mobile approach of loading JavaScript in comments and then pulling that
code out and eval()ing it.

I still feel very strongly that this pattern is a necessary evolution of
how we should be able to load scripts into web pages. I just want a flag
that says don't execute this now and a method to say okay, execute this
now. Allowing that flag to be set both in HTML and JavaScript is ideal.

The question of dependency management is, in my mind, a separate issue and
one that doesn't belong in this layer of the web platform. HTML isn't the
right spot for a dependency tree to be defined for scripts (or anything
else). To me, that is a problem to be solved within the ECMAScript world
much the way CSS has @import available from within CSS code.

I think the use cases other than the initial one (preload/execute later)
are best relegated to script loaders and are very tied to a current way of
thinking about loading JavaScript. I'd rather provide a simple, low-level
piece of functionality that make the job of script loaders easier by
providing a reliable API and then let the dependency management use cases
be addressed outside of HTML.

Other random thoughts:

* whenneeded is a very strange name for that attribute. It doesn't really
tell me anything, as opposed to preload, noexecute, or future. How do
I know when it will be needed?

* I like execute() as the way to run the script in question.


-N





On Thu, Aug 29, 2013 at 5:58 AM, Brian Kardell bkard...@gmail.com wrote:

 On Aug 29, 2013 1:21 AM, Jonas Sicking jo...@sicking.cc wrote:
 
  Hi Ryosuke,
 
  Based on the feedback here, it doesn't sound like you are a huge fan
  of the original proposal in this thread.
 
  At this point, has any implementation come out in support of the
  proposal in this thread as a preferred solution over
  noexecute/execute()?
 
  The strongest support I've seen in this thread, though I very well
  could have missed some, is it's better than status quo.
 
  Is that the case?
 
  / Jonas
 
  On Wed, Aug 28, 2013 at 7:43 PM, Ryosuke Niwa rn...@apple.com wrote:
   On Jul 13, 2013, at 5:55 AM, Andy Davies dajdav...@gmail.com wrote:
  
   On 12 July 2013 01:25, Bruno Racineux br...@hexanet.net wrote:
  
   On browser preloading:
  
   There seems to an inherent conflict between 'indiscriminate'
 Pre-parsers/
   PreloadScanner and responsive design for mobile. Responsive designs
   mostly implies that everything needed for a full screen desktop is
   provided in markup to all devices.
  
  
   The pre-loader is a tradeoff, it's aiming to increase network
 utilisation
   by speculatively downloading resources it can discover.
  
   Some of the resources downloaded may be not be used but with good
 design
   and mobile first approaches hopefully this number can be minimised.
  
   Even if some unused resources get downloaded how much it matter?
  
   It matters a lot when you only have GSM wireless connection, and barely
 loading anything at all.
  
   By starting the downloads earlier, connections will be opened sooner,
 and
   the TCP congestion window to grow sooner. Of course this has to be
 balanced
   against visitors who might be paying to download those unused bytes,
 and
   whether the unused resources are blocking something on the critical
 path
   from being downloaded (believe some preloaders can re-prioritise
 resources
   if they need them before the preloader has downloaded them)
  
   Exactly.  I'd to make sure whatever API we come up gives enough
 flexibility for the UAs to decide whether a given resource needs to be
 loaded immediatley.
  
  
  
   On Jul 12, 2013, at 11:56 AM, Kyle Simpson get...@gmail.com wrote:
  
   My scope (as it always has been) put simply: I want (for all the
 reasons here and before) to have a silver bullet in script loading, which
 lets me load any number of scripts in parallel, and to the extent that is
 reasonable, be fully in control of what order they run in, if at all,
 responding to conditions AS THE SCRIPTS EXECUTE, not merely as they might
 have existed at the time of initial request. I want such a facility because
 I want to continue to have LABjs be a best-in-class fully-capable script
 loader that sets the standard for best-practice on-demand script loading.
  
  
   Because of the different network conditions and constraints various
 devices have, I'm wary of any solution that gives the full control over
 when each script is loaded.  While I'm sure large corporations with lots of
 resources will get this right, I don't want to provide a preloading API
 

Re: [whatwg] Script preloading

2013-08-29 Thread Jake Archibald
On 27 August 2013 22:55, Ian Hickson i...@hixie.ch wrote:

 On Tue, 9 Jul 2013, Bruno Racineux wrote:
 
  Why not simply load all such scripts early in the head with 'defer',
  which preserves the dependency order as determined by your app. Using
  'defer' in head scripts is actually a very good way to preserve script
  order with non-blocking scripts. And by loading the scripts very early
  in the head, the possibility of a incurred significant delay of
  DOMContentLoaded, for an eventual large script not yet downloaded, is
  minimal to none.

 This doesn't seem like it handles all the use cases (e.g. T and U).


Worth noting that defer is busted in IE9 and below, to the point where it's
unusable https://github.com/h5bp/lazyweb-requests/issues/42


  I would also strongly favor restoring the previous spec portion of
  'defer' which allow to have defer on inline script blocks (i.e. if the
  src attribute is not present). I don't know why this html4 functionality
  was removed from html5?

 Well, primarily because basically nobody implemented it, but also, because
 it's not clear what the point is. Why would you need it?


I like my scripts to be inert, as in have no impact on the page (like
jquery). I use a small inline script to start the work needed for that
page, meaning I know the starting point for all JS interacting with the
page is somewhere in an inline script. This is much easier to maintain than
scripts that trigger themselves ondomready depending on what they see in
the DOM.

I'd have liked defer (to work in IE and) to work on scripts without src. In
your proposal, does this work?…

script src=whatever.js whenneeded/script
...
script needs=whatever.js
   activateTheAlmightyWebsockets();
/script


 On Mon, 15 Jul 2013, Kornel Lesiński wrote:
  ES6 modules however do not solve the performance problem. In fact they
  would benefit from UA having a list of all dependencies up front
  (otherwise file's dependencies can only be discovered after that file is
  loaded, which costs as many RTTs as the height of the dependency tree).
 
  So I think that eventually ES6 modules + link[rel=subresource] could be
  the answer. The link would expose URLs to (pre)load for performance,
  but modules would handle actual loading/execution for flexibility and
  reliability.

 The ES6 module doesn't address some of the use cases above, as far as I
 can tell (e.g. Q, U) and require a lot of work to handle some of the
 others. But it seems important that anything we add to HTML be designed to
 work with ES6 modules on the long run.


There seems to be a lack of data on how modules would work in the browser.
Eg, when/if they block further rendering. Or is that in the doc  I'm just
not getting my head around it?

It'd be great if modules can solve these but also give the UA all the
requirements up front (or maybe that's the job of HTTP2).


 On Wed, 10 Jul 2013, Jake Archibald wrote:
 
  If dependencies took a CSS selector it could be:
 
  script dependencies=.cms-core src=cmd-plugin.js/script
 
  Now the number of scripts with class cms-core can change between
  versions of the CMS but the plugin still waits for them all. No ID
  generation needed.

 Using a selector is an interesting idea.

 It makes it harder to detect and prevent loops, but not fatally so.


I'm not sure it's possible to get into loops with this. I imagined
dependency resolution to happen once, on element creation or adding to
document (whichever happens latest). So with:

script src=a.js needs=script[src=b.js]/script
script src=b.js needs=script[src=a.js]/script

…the first script would have zero dependencies, because the selector
matches zero elements. The second would depend on the first, so the
execution order is a.js, b.js. The thing I like about the selector thing is
you can very easily get (almost) async=false behaviour:

script src=a.js needs=script/script
script src=b.js needs=script/script
script src=c.js needs=script/script


   script elements get a new whenneeded= attribute, which delays the
   execution of the script until the script element's execute() method is
   called. (This essentially provides the same as the preload
   suggestions.)


execute() should return a promise that resolves when the script
successfully downloads and executes. Also, should there be an event on the
script element when the script has downloaded, but not executed (like IE
used to have)?

(there's probably a better name than whenneeded, but I can't think of one
right now)


   script elements also get a new needs= attribute, which takes a list
   of URLs. A script won't run (even if you call execute()) until all the
   script src= elements referenced by its needs= attribute are
   themselves ready to run. For example:

  script src=b.js needs=a.js/script
  script src=a.js async/script


It seems weird to refer to needs by url, but still require script
elements for those needs, I'd rather use IDs (or selectors yey!). Also, I'm
not sure we need to deal 

Re: [whatwg] Script preloading

2013-08-29 Thread Ryosuke Niwa
On Aug 29, 2013, at 8:37 AM, Nicholas Zakas standa...@nczconsulting.com wrote:

 When Kyle and I originally started pushing for a way to preload JavaScript 
 many moons ago, the intent was very simple: to allow the downloading of 
 JavaScript and execution of JavaScript to be separate. The idea being that 
 you should be able to preload scripts that you'll need later without 
 incurring the cost of parsing and execution at that point in time. There are 
 many examples of people doing this, the most famous being the Gmail mobile 
 approach of loading JavaScript in comments and then pulling that code out and 
 eval()ing it.
 
 I still feel very strongly that this pattern is a necessary evolution of how 
 we should be able to load scripts into web pages. I just want a flag that 
 says don't execute this now and a method to say okay, execute this now. 
 Allowing that flag to be set both in HTML and JavaScript is ideal.
 
 The question of dependency management is, in my mind, a separate issue and 
 one that doesn't belong in this layer of the web platform. HTML isn't the 
 right spot for a dependency tree to be defined for scripts (or anything 
 else). To me, that is a problem to be solved within the ECMAScript world much 
 the way CSS has @import available from within CSS code. 

But why do you want an ability to say don't execute this now if there were no 
dependencies?  Loading an extra script file that's not needed immediately can 
add few hundred of milliseconds to the total page load time over a slow network 
connection.

To put it another way, I don't see why anyone wants to load a script and not 
execute it other than for the purpose of avoiding the network request at a 
later time.  However, if that were the main purpose of providing such a 
functionality, then we also need to address the issue of this load request 
needing to have a lower priority than other load requests that are vital for 
the page.  In fact, we might want to avoid sending the request of a script file 
altogether if the user isn't going to interact the parts of the page that needs 
such a script.

- R. Niwa



Re: [whatwg] Script preloading

2013-08-29 Thread Glenn Maynard
On Tue, Aug 27, 2013 at 4:55 PM, Ian Hickson i...@hixie.ch wrote:

 IMHO, if you have to write a script to solve use cases like these, you
 haven't really solved the use cases. It seems that the opportunity we have
 here is to provide a feature or set of features that addresses these use
 cases directly, so that anyone can use them without much work.


This is especially true for a module loader, which will be used to deal
with interactions between scripts written by different parties.  If the
platform doesn't provide a standard, universal way to do this, then people
will keep rolling their own incompatible solutions.  That's bearable for
self-contained code used by a module, but it doesn't make sense for the
piece that handles the cross-vendor interactions.

Anyway, the idea of only providing basic building blocks and making people
roll their own solutions isn't the web's design philosophy at all, so I
don't think it's a valid objection.


  script whenneeded=jit is a special mode where instead of running once
  the script's dependencies are met, it additionally waits until all the
  scripts that depend on _it_ are ready to run. (Just in time exection.)
  (The default is whenneeded=asap, as soon as possible exection.)


This mode seems to be specifically for this use case:

 [Use-case U:] I have a set of script A.js, B.js, and C.js. B
 relies on A, and C relies on B. So they need to execute strictly in that
 order. [Now], imagine they progressively render different parts of a
 widget. [...] I only want to execute A, B and C once all 3 are preloaded
 and ready to go. It's [...] about minimizing delays between them, for
 performance PERCEPTION.

This one seems uncommon, and less like a dependency use case than the
others.  How often is this wanted?  Is it too inconvenient to just mark
them all @whenneeded, and say something like:

document.querySelector(#C).execute(function() {
A.render();
B.render();
C.render();
});

That does require the modules render in a function, and not when the script
is first executed.  I don't know how much of a burden that is for this
case.

Alternatively, if an event is fired when a script's dependencies have been
met, then you could mark all three scripts @whenneeded, and call
(#C).execute() once C's dependencies have been met.

Maybe the jit feature isn't a big deal, but it seems like a bit of an
oddball for a narrow use case.

 You can manually increase or decrease a dependency count on script
  elements by calling incDependencies() and decDependencies().


Will a @defer dependency effectively defer all scripts that depend on it?

incDependencies() and decDependencies() may be hard to debug, since if
somebody messes up the counter, it's hard to tell whose fault it is.  A
named interface could help with this: script.addDependency(thing); /*
script.dependencies is now [thing] */ script.removeDependency(thing);


On Thu, Aug 29, 2013 at 10:37 AM, Nicholas Zakas 
standa...@nczconsulting.com wrote:

 The question of dependency management is, in my mind, a separate issue and
 one that doesn't belong in this layer of the web platform. HTML isn't the
 right spot for a dependency tree to be defined for scripts (or anything
 else). To me, that is a problem to be solved within the ECMAScript world
 much the way CSS has @import available from within CSS code.


This would serialize script loading, because you wouldn't know a script's
dependencies until you've actually fetched the script.  That would make
page loads very slow.

I think the use cases other than the initial one (preload/execute later)
 are best relegated to script loaders


I disagree.  See above.

(Please remember to trim quotes.)

-- 
Glenn Maynard


Re: [whatwg] Script preloading

2013-08-29 Thread Garrett Smith
On 8/29/13, Nicholas Zakas standa...@nczconsulting.com wrote:
 When Kyle and I originally started pushing for a way to preload JavaScript
 many moons ago, the intent was very simple: to allow the downloading of
 JavaScript and execution of JavaScript to be separate. The idea being that
 you should be able to preload scripts that you'll need later without
 incurring the cost of parsing and execution at that point in time. There
 are many examples of people doing this, the most famous being the Gmail
 mobile approach of loading JavaScript in comments and then pulling that
 code out and eval()ing it.


Ian mentioned the idea of exporting a module, and that idea requires
only a function expression to return an object. This requires the
parsing of one function -- the outermost function -- which can be
evaluated later.

Some examples of this include the Russian Doll Pattern (Cornford)
Module Pattern (Crockford), IIFE (?), and function rewriting (me).

For more on this, see Kangax' article:
http://kangax.github.io/nfe/

(Kangax seems to have gotten bored at conquering javascript these days).

 I still feel very strongly that this pattern is a necessary evolution of
 how we should be able to load scripts into web pages. I just want a flag
 that says don't execute this now and a method to say okay, execute this
 now. Allowing that flag to be set both in HTML and JavaScript is ideal.

 The question of dependency management is, in my mind, a separate issue and
 one that doesn't belong in this layer of the web platform. HTML isn't the
 right spot for a dependency tree to be defined for scripts (or anything
 else). To me, that is a problem to be solved within the ECMAScript world
 much the way CSS has @import available from within CSS code.

Dependency issues include problems from having to block for scripts,
document.write, fouc.

Problems arising with dependency stem give rise to the need of
deferring and executing scripts. The problem is that the program needs
to run a script during a certain condition. And if that condition is
not met, then the script resource isn't needed at all.

This could useful for a situation where there are a few different
components on a page, say each component requires 100k of script and
10k of CSS. But the user will probably only use one of those three
components and might very well use none at all. I have worked on pages
like that, with sidebars, pickers, and panels, and I wanted something
like this.

As Ryosuke pointed out, the idea is to declare the script in the page
and then use script to determine when it should load.

My previous post on building a dependency tree delves into the idea
that CSS and JS can be declared to depend on stuff being loaded.  That
feature makes it obvious as to why they're in the source code, to the
human reader.

Regards,
-- 
Garrett
Twitter: @xkit
personx.tumblr.com


Re: [whatwg] Script preloading

2013-08-28 Thread Ryosuke Niwa
On Jul 13, 2013, at 5:55 AM, Andy Davies dajdav...@gmail.com wrote:

 On 12 July 2013 01:25, Bruno Racineux br...@hexanet.net wrote:
 
 On browser preloading:
 
 There seems to an inherent conflict between 'indiscriminate' Pre-parsers/
 PreloadScanner and responsive design for mobile. Responsive designs
 mostly implies that everything needed for a full screen desktop is
 provided in markup to all devices.
 
 
 The pre-loader is a tradeoff, it's aiming to increase network utilisation
 by speculatively downloading resources it can discover.
 
 Some of the resources downloaded may be not be used but with good design
 and mobile first approaches hopefully this number can be minimised.
 
 Even if some unused resources get downloaded how much it matter?

It matters a lot when you only have GSM wireless connection, and barely loading 
anything at all.

 By starting the downloads earlier, connections will be opened sooner, and
 the TCP congestion window to grow sooner. Of course this has to be balanced
 against visitors who might be paying to download those unused bytes, and
 whether the unused resources are blocking something on the critical path
 from being downloaded (believe some preloaders can re-prioritise resources
 if they need them before the preloader has downloaded them)

Exactly.  I'd to make sure whatever API we come up gives enough flexibility for 
the UAs to decide whether a given resource needs to be loaded immediatley.



On Jul 12, 2013, at 11:56 AM, Kyle Simpson get...@gmail.com wrote:

 My scope (as it always has been) put simply: I want (for all the reasons here 
 and before) to have a silver bullet in script loading, which lets me load 
 any number of scripts in parallel, and to the extent that is reasonable, be 
 fully in control of what order they run in, if at all, responding to 
 conditions AS THE SCRIPTS EXECUTE, not merely as they might have existed at 
 the time of initial request. I want such a facility because I want to 
 continue to have LABjs be a best-in-class fully-capable script loader that 
 sets the standard for best-practice on-demand script loading.


Because of the different network conditions and constraints various devices 
have, I'm wary of any solution that gives the full control over when each 
script is loaded.  While I'm sure large corporations with lots of resources 
will get this right, I don't want to provide a preloading API that's hard to 
use for ordinary Web developers.


On Jul 15, 2013, at 7:55 AM, Kornel Lesiński kor...@geekhood.net wrote:

 There's a very high overlap between module dependencies and script 
 dependencies proposal. I think at very least it would be useful to define 
 script dependencies in terms of ES6 modules, or even abandon markup 
 solution to avoid duplicating features.
 
 ES6 modules however do not solve the performance problem. In fact they would 
 benefit from UA having a list of all dependencies up front (otherwise file's 
 dependencies can only be discovered after that file is loaded, which costs as 
 many RTTs as the height of the dependency tree).
 
 So I think that eventually ES6 modules + link[rel=subresource] could be the 
 answer. The link would expose URLs to (pre)load for performance, but 
 modules would handle actual loading/execution for flexibility and reliability.


Yes, we should definitely consider how this preloading API works with ES6 
modules.



On Jul 22, 2013, at 3:22 PM, Jonas Sicking jo...@sicking.cc wrote:

 Having the load event anytime we are done with a network request also
 seems beneficial. Rather than having most APIs use load whereas this
 would use preload.
 
 Generally speaking load means loaded and processed. The
 'noexecute' flag would change what the and processed piece includes.

I don't think it'll be confusing if the script had noexecute.  We can even call 
it noautoexecute if we wanted.

 But I'm fine either way here. The same question and risk of confusion
 seems to exist with the whenneeded attribute. In general
 whenneeded seems very similar to noexecute, but with a little bit
 more stuff done automatically, for better or worse.

I like the simplicity of noexecute and excute().  However, I'm a little worried 
that it doesn't provide any information as to how important a given script is.  
So Web browsers have no choice but to request all scripts immediately.

I'd like to eventually provide APIs that allow authors to codify which scripts 
are vital so that Web browsers can properly prioritize each script request.

Implementation wise, noexecute/execute() will be extremely easy to implement in 
WebKit.

 I.e. something like:
 
 script src=script1.js id=s1
 script src=script2.js dependencies=s1
 
 would run correctly in downlevel browsers, but would force the scripts
 to be blocking.
 
 script src=script1.js id=s1 async
 script src=script2.js async dependencies=s1
 
 would give you performant non-blocking behavior in downlevel browsers,
 but at the expense of the scripts not always running 

Re: [whatwg] Script preloading

2013-08-28 Thread Jonas Sicking
Hi Ryosuke,

Based on the feedback here, it doesn't sound like you are a huge fan
of the original proposal in this thread.

At this point, has any implementation come out in support of the
proposal in this thread as a preferred solution over
noexecute/execute()?

The strongest support I've seen in this thread, though I very well
could have missed some, is it's better than status quo.

Is that the case?

/ Jonas

On Wed, Aug 28, 2013 at 7:43 PM, Ryosuke Niwa rn...@apple.com wrote:
 On Jul 13, 2013, at 5:55 AM, Andy Davies dajdav...@gmail.com wrote:

 On 12 July 2013 01:25, Bruno Racineux br...@hexanet.net wrote:

 On browser preloading:

 There seems to an inherent conflict between 'indiscriminate' Pre-parsers/
 PreloadScanner and responsive design for mobile. Responsive designs
 mostly implies that everything needed for a full screen desktop is
 provided in markup to all devices.


 The pre-loader is a tradeoff, it's aiming to increase network utilisation
 by speculatively downloading resources it can discover.

 Some of the resources downloaded may be not be used but with good design
 and mobile first approaches hopefully this number can be minimised.

 Even if some unused resources get downloaded how much it matter?

 It matters a lot when you only have GSM wireless connection, and barely 
 loading anything at all.

 By starting the downloads earlier, connections will be opened sooner, and
 the TCP congestion window to grow sooner. Of course this has to be balanced
 against visitors who might be paying to download those unused bytes, and
 whether the unused resources are blocking something on the critical path
 from being downloaded (believe some preloaders can re-prioritise resources
 if they need them before the preloader has downloaded them)

 Exactly.  I'd to make sure whatever API we come up gives enough flexibility 
 for the UAs to decide whether a given resource needs to be loaded immediatley.



 On Jul 12, 2013, at 11:56 AM, Kyle Simpson get...@gmail.com wrote:

 My scope (as it always has been) put simply: I want (for all the reasons 
 here and before) to have a silver bullet in script loading, which lets me 
 load any number of scripts in parallel, and to the extent that is 
 reasonable, be fully in control of what order they run in, if at all, 
 responding to conditions AS THE SCRIPTS EXECUTE, not merely as they might 
 have existed at the time of initial request. I want such a facility because 
 I want to continue to have LABjs be a best-in-class fully-capable script 
 loader that sets the standard for best-practice on-demand script loading.


 Because of the different network conditions and constraints various devices 
 have, I'm wary of any solution that gives the full control over when each 
 script is loaded.  While I'm sure large corporations with lots of resources 
 will get this right, I don't want to provide a preloading API that's hard to 
 use for ordinary Web developers.


 On Jul 15, 2013, at 7:55 AM, Kornel Lesiński kor...@geekhood.net wrote:

 There's a very high overlap between module dependencies and script 
 dependencies proposal. I think at very least it would be useful to define 
 script dependencies in terms of ES6 modules, or even abandon markup 
 solution to avoid duplicating features.

 ES6 modules however do not solve the performance problem. In fact they would 
 benefit from UA having a list of all dependencies up front (otherwise file's 
 dependencies can only be discovered after that file is loaded, which costs 
 as many RTTs as the height of the dependency tree).

 So I think that eventually ES6 modules + link[rel=subresource] could be the 
 answer. The link would expose URLs to (pre)load for performance, but 
 modules would handle actual loading/execution for flexibility and 
 reliability.


 Yes, we should definitely consider how this preloading API works with ES6 
 modules.



 On Jul 22, 2013, at 3:22 PM, Jonas Sicking jo...@sicking.cc wrote:

 Having the load event anytime we are done with a network request also
 seems beneficial. Rather than having most APIs use load whereas this
 would use preload.

 Generally speaking load means loaded and processed. The
 'noexecute' flag would change what the and processed piece includes.

 I don't think it'll be confusing if the script had noexecute.  We can even 
 call it noautoexecute if we wanted.

 But I'm fine either way here. The same question and risk of confusion
 seems to exist with the whenneeded attribute. In general
 whenneeded seems very similar to noexecute, but with a little bit
 more stuff done automatically, for better or worse.

 I like the simplicity of noexecute and excute().  However, I'm a little 
 worried that it doesn't provide any information as to how important a given 
 script is.  So Web browsers have no choice but to request all scripts 
 immediately.

 I'd like to eventually provide APIs that allow authors to codify which 
 scripts are vital so that Web browsers can properly prioritize each 

[whatwg] Script preloading

2013-08-27 Thread Ian Hickson

First, let's get down to use cases. Kyle did a great job of describing 
some key use cases:

On Wed, 10 Jul 2013, Kyle Simpson wrote:

 [Use-case Q:] I am dynamically loading one of those social widgets that, 
 upon load, automatically scans a page and renders social buttons. I need 
 to be able to preload that script so it's ready to execute, but decide 
 when I want it to run against the page. I don't want to wait for true 
 on-demand loading, like when my user clicks a button, because of the 
 loading delay that will be visible to the user, so I want to pre-load 
 that script and have it waiting, ready at a moment's notice to say it's 
 ok to execute, do it now! now! now!.

 [Use-case S:] One CMS plugin wants to load A.js and B.js, where B 
 relies on A. Both need to load in parallel (for performance), but A must 
 execute before B executes. I don't control A and B, so changing them is 
 not an option. This CMS plugin [wants] to wait for some 
 user-interaction, such as a button click, before executing the code. We 
 don't want there to be any big network-loading delay visible to the user 
 between their click of the button and the running of that plugin's code.
 
 Another CMS plugin on this same page wants to load A.js, C.js, and 
 D.js. This plugin doesn't know or care that the other plugin also 
 requests A.js. It doesn't know if there is a script element in the 
 page requesting it or not, and it doesn't want to looking for it. It 
 just wants to ask for A as a pre-requisite to C and D. But C and D have 
 no dependency on each other, only a shared dependency on A. C and D 
 should be free to run ASAP (in whichever order), assuming that A has 
 already run [once] some user-interaction that initiates the load of A, 
 C, and D. This user interaction may be before the other plugin requested 
 A, or after it requested A.

 A.js can be requested relatively (via a base tag or just relative to 
 document root) or absolutely, or it might be requested with the 
 leading-// protocol-relative from, taking on whatever http or https 
 protocol the page has, whereas other references to it may specify the 
 prototcol.

 These plugins can't guarantee what ID's or classes they use are reliably 
 unique without undue processing burden.

[I've trimmed the text Kyle wrote here, but also implicit in his 
description, as I understood it, was that A.js should only run once even 
if both plugins tried to load it.]

 [Use-case T:] I have two different calendar widgets. I want to pop one 
 of them up when a user clicks a button. The user may never click the 
 button, in which case I don't want the calendar widget to have ever 
 executed to render. [...]
 
 It'd be nice if both calendar widgets were built sensibly so that 
 loading the code didn't automatically render. One of them IS, the other 
 is unfortunately mis-behaving, and it will render itself as soon as its 
 code is run. [...]
 
 Furthermore, these two widgets are not equal. Perhaps one is better 
 for smaller browser window sizes, and the other is better for larger 
 browser windows. [...]
 
 Regardless, the point is, there's run-time conditions which are going to 
 determine if I want to execute calendar widget A or B, or maybe I never 
 execute either. But I want them both preloaded and ready to go, just in 
 case, so that if the user DOES need one, it's free and ready to execute 
 with nearly no delay, instead of having to wait to request as I would 
 with only on-demand techniques.

 [Use-case U:] I have a set of script A.js, B.js, and C.js. B 
 relies on A, and C relies on B. So they need to execute strictly in that 
 order. [Now], imagine they progressively render different parts of a 
 widget. [...] I only want to execute A, B and C once all 3 are preloaded 
 and ready to go. It's [...] about minimizing delays between them, for 
 performance PERCEPTION.

 [For example, one of them might start playing a video, and another might 
 introduce the canvas slides for that video. You want all of the 
 relevant scripts to be run at once, so there's no point where the page 
 has a video element but doesn't have the canvas.]

On Thu, 11 Jul 2013, Kyle Simpson wrote:
 
 [Use-case V:] you have a string of scripts (A.js, B.js, and C.js) 
 loading which constitute a dependency chain. A must run before B, which 
 must run before C. However, if you detect an error in loading, you stop 
 the rest of the executions (and preferably loading too!), since clearly 
 dependencies will fail for further scripts, and the errors will just 
 unnecessarily clutter the developer console log making it harder to 
 debug.

 [Use-case W:] some developers have even requested to be able to stop the 
 chain and prevent further executions if the script loads, but there's 
 some compile-time syntax error or run-time error that happens during the 
 execution. For them, it's not enough for B to simply finish loading 
 successfully, but that it must fully execute without error.

On Sun, 14 Jul 2013, 

Re: [whatwg] Script preloading

2013-07-22 Thread Jake Archibald
On 18 July 2013 23:28, Kyle Simpson get...@gmail.com wrote:
 About a week ago, I presented a set of code comparing the script 
 dependencies=.. approach to the script preload approach, as far as 
 creating generalized script loaders.

 There were a number of concerns presented in those code snippets, and the 
 surrounding discussions. I asked for input on the code and the issues raised.

 Later in the thread, I also identified issues with needing to more robustly 
 handle error recovery and it was suggested that Navigation Controller was a 
 good candidate for partnering with script loading for this task. I asked for 
 some code input in that respect as well.

 AFAICT, the thread basically went dormant at roughly the same time.

As said on Twitter
(https://twitter.com/jaffathecake/status/355436953929388034) I've been
on leave for a week. As you might imagine I'm riddled with emails as a
result. Working through them. You will get a reply.


Re: [whatwg] Script preloading

2013-07-22 Thread Jonas Sicking
On Tue, Jul 9, 2013 at 12:39 PM, Ian Hickson i...@hixie.ch wrote:
 The proposals I've seen so far for extending the spec's script preloading
 mechanisms fall into two categories:

  - provide some more control over the mechanisms already there, e.g.
firing events at various times, adding attributes to make the script
loading algorithm work differently, or adding methods to trigger
particular parts of the algorithm under author control.

  - provide a layer above the current algorithm that provides strong
semantics, but that doesn't have much impact on the loading algorithm
itself.

 I'm very hesitant to do the first of these, because the algorithm is _so_
 complicated that adding anything else to it is just going to result in
 bugs in browsers. There comes a point where an algorithm just becomes so
 hard to accurately test that it's a lost cause.

 The second seems more feasible, though.

FWIW, I don't really know what functionality you put in the first
category, and what you put in the second.

However, as an implementor, I definitely think that the current
proposal is more complicated to implement than the proposal that I
pushed for before. I.e. adding a noexecute attribute on the script
element which causes the script element not to execute when it
normally would. Instead it fires the load event when the script has
been loaded and does nothing more.

Once the page wants the script to execute, it would call a new
.execute() function on the script which would cause the loaded script
to execute. If the function is called before the load event has fired,
an InvalidStateError exception would be thrown.

I could absolutely believe that this is harder to specify than your
proposal. I haven't looked at the spec in enough detail to know. But
it's definitely easier to implement in at least Gecko. I'd be
interested to hear what other implementors think. And implementations
have a higher priority than spec writing in the hierarchy of
constituents.

I also think it's a simpler model for authors to understand.

Now, even higher priority in the hierarchy of constituents are
authors. So if your proposal above is written with the goal of
creating something authors prefer over the noexecute proposal, then
that definitely seems like the right goal. I haven't read enough of
the feedback here to get a clear picture of if the proposal in this
thread is considered better than noexecute.

I could definitely see that the dependencies feature could be
attractive if it indeed would let authors avoid manually scheduling
scripts for execution. But as always when building high-level
features, there's a risk that if they don't solve the use-cases
exactly, that they won't get used.

/ Jonas


Re: [whatwg] Script preloading

2013-07-22 Thread Kyle Simpson
FWIW, I'd be much more in favor of Jonas' proposal, at this point, than the 
dependencies=.. proposal. The `noexecute/execute()` is conceptually pretty 
similar to the preload proposal I've been pushing. As far as I can tell from 
how Jonas describes it, it looks like it would fit most of the use-cases I've 
put forth as caring about.

There's a few details to iron out, however:

1. Will it cause confusion for authors that the behavior of the `onload` event 
on script elements is modified from its current long-standing loaded and 
executed to just loaded when in the presence of the `noexecute` 
attribute/property? Seems like it could cause a fair bit of confusion.

That's why the preload proposal proposed another event (`onpreload`), to reduce 
the conflation/confusion. But it might be tenable for authors. I'm sure as a 
script loader author I can work around it just fine if I need to.



2. What will the interaction be, if any different, with the `onerror` events? 
Script preloading not-withstanding, there's little cross-browser compatibility 
on the topic of just what exactly constitutes a script error event. Some 
browsers fire it for all of the common network error conditions (404, 5xx), 
others only some of them.

In particular, if we're just building off existing mechanisms and not inventing 
whole new ones, it would be nice, from an author perspective, if EITHER the 
`onload` or the `onerror` event ALWAYS fired, and never both, and never 
neither, and if it was consistent when each happened.

I asked a couple of years ago on this list for that exact thing to be clarified 
in the spec, and was told at that time that implementors were left with the 
discretion, which accounted for the disparity. I of course would renew my 
request to reverse that and land on some common spec.



3. The main reason people seem to favor the `dependencies=..` proposal or its 
variants is the idea of markup-only preloading, where the loading of a 
subsequent script tag or tags can implicitly be the signal to execute another 
previously loaded-and-waiting script. Not clear if/how Jonas' proposal could 
suit that view. Perhaps similar to how I proposed handling that desire in the 
preload proposal.



--Kyle




On Jul 22, 2013, at 4:00 PM, Jonas Sicking jo...@sicking.cc wrote:

 On Tue, Jul 9, 2013 at 12:39 PM, Ian Hickson i...@hixie.ch wrote:
 The proposals I've seen so far for extending the spec's script preloading
 mechanisms fall into two categories:
 
 - provide some more control over the mechanisms already there, e.g.
   firing events at various times, adding attributes to make the script
   loading algorithm work differently, or adding methods to trigger
   particular parts of the algorithm under author control.
 
 - provide a layer above the current algorithm that provides strong
   semantics, but that doesn't have much impact on the loading algorithm
   itself.
 
 I'm very hesitant to do the first of these, because the algorithm is _so_
 complicated that adding anything else to it is just going to result in
 bugs in browsers. There comes a point where an algorithm just becomes so
 hard to accurately test that it's a lost cause.
 
 The second seems more feasible, though.
 
 FWIW, I don't really know what functionality you put in the first
 category, and what you put in the second.
 
 However, as an implementor, I definitely think that the current
 proposal is more complicated to implement than the proposal that I
 pushed for before. I.e. adding a noexecute attribute on the script
 element which causes the script element not to execute when it
 normally would. Instead it fires the load event when the script has
 been loaded and does nothing more.
 
 Once the page wants the script to execute, it would call a new
 .execute() function on the script which would cause the loaded script
 to execute. If the function is called before the load event has fired,
 an InvalidStateError exception would be thrown.
 
 I could absolutely believe that this is harder to specify than your
 proposal. I haven't looked at the spec in enough detail to know. But
 it's definitely easier to implement in at least Gecko. I'd be
 interested to hear what other implementors think. And implementations
 have a higher priority than spec writing in the hierarchy of
 constituents.
 
 I also think it's a simpler model for authors to understand.
 
 Now, even higher priority in the hierarchy of constituents are
 authors. So if your proposal above is written with the goal of
 creating something authors prefer over the noexecute proposal, then
 that definitely seems like the right goal. I haven't read enough of
 the feedback here to get a clear picture of if the proposal in this
 thread is considered better than noexecute.
 
 I could definitely see that the dependencies feature could be
 attractive if it indeed would let authors avoid manually scheduling
 scripts for execution. But as always when building high-level
 features, there's a risk that if they 

Re: [whatwg] Script preloading

2013-07-22 Thread Jonas Sicking
On Mon, Jul 22, 2013 at 2:35 PM, Kyle Simpson get...@gmail.com wrote:
 FWIW, I'd be much more in favor of Jonas' proposal, at this point, than the 
 dependencies=.. proposal. The `noexecute/execute()` is conceptually pretty 
 similar to the preload proposal I've been pushing. As far as I can tell from 
 how Jonas describes it, it looks like it would fit most of the use-cases I've 
 put forth as caring about.

 There's a few details to iron out, however:

 1. Will it cause confusion for authors that the behavior of the `onload` 
 event on script elements is modified from its current long-standing loaded 
 and executed to just loaded when in the presence of the `noexecute` 
 attribute/property? Seems like it could cause a fair bit of confusion.

 That's why the preload proposal proposed another event (`onpreload`), to 
 reduce the conflation/confusion. But it might be tenable for authors. I'm 
 sure as a script loader author I can work around it just fine if I need to.

Do you have a link to your preload proposal?

Either way, I agree about the concern with onload. I personally have a
hard time telling if it'll be confusing.

Having the load event anytime we are done with a network request also
seems beneficial. Rather than having most APIs use load whereas this
would use preload.

Generally speaking load means loaded and processed. The
'noexecute' flag would change what the and processed piece includes.

But I'm fine either way here. The same question and risk of confusion
seems to exist with the whenneeded attribute. In general
whenneeded seems very similar to noexecute, but with a little bit
more stuff done automatically, for better or worse.

 2. What will the interaction be, if any different, with the `onerror` events? 
 Script preloading not-withstanding, there's little cross-browser 
 compatibility on the topic of just what exactly constitutes a script error 
 event. Some browsers fire it for all of the common network error conditions 
 (404, 5xx), others only some of them.

There are three opportunities to fire error stuff here:

1. Failed network request
2. Failed JS compilation
3. Exception thrown from execution

And there are two error reporting mechanisms in play

A. Fire an error event on the script element.
B. Fire the window.onerror callback (like an event, but not exactly the same).

1 and 2 seems like they could behave exactly the same for noexecute
scripts as for normal scripts. I'm not sure if that includes firing
both A and B in current browsers? This would require implementations
to do syntax checking (though not full compilation) of the script even
before the execute() function is called. I *think* this is ok, but I'm
not sure. Measurements in browsers would likely be needed.

3 presumably only triggers B currently for normal scripts?

 In particular, if we're just building off existing mechanisms and not 
 inventing whole new ones, it would be nice, from an author perspective, if 
 EITHER the `onload` or the `onerror` event ALWAYS fired, and never both, and 
 never neither, and if it was consistent when each happened.

 I asked a couple of years ago on this list for that exact thing to be 
 clarified in the spec, and was told at that time that implementors were left 
 with the discretion, which accounted for the disparity. I of course would 
 renew my request to reverse that and land on some common spec.

Indeed. Though we're only talking about the A mechanism about, right?

I.e. the following would cause both a load event to be fired on the
script, and window.onerror to be triggered?

script src=data:text/plain,throw new Error();/script

I would definitely be in support of that. Though compatibility with
existing content could be a problem.

 3. The main reason people seem to favor the `dependencies=..` proposal or its 
 variants is the idea of markup-only preloading, where the loading of a 
 subsequent script tag or tags can implicitly be the signal to execute another 
 previously loaded-and-waiting script. Not clear if/how Jonas' proposal could 
 suit that view. Perhaps similar to how I proposed handling that desire in the 
 preload proposal.

Can we get a good markup-only solution while still keeping both
acceptable performance as well as correct functionality in downlevel
browsers?

I.e. something like:

script src=script1.js id=s1
script src=script2.js dependencies=s1

would run correctly in downlevel browsers, but would force the scripts
to be blocking.

script src=script1.js id=s1 async
script src=script2.js async dependencies=s1

would give you performant non-blocking behavior in downlevel browsers,
but at the expense of the scripts not always running in scripts in the
right order.

/ Jonas




 --Kyle




 On Jul 22, 2013, at 4:00 PM, Jonas Sicking jo...@sicking.cc wrote:

 On Tue, Jul 9, 2013 at 12:39 PM, Ian Hickson i...@hixie.ch wrote:
 The proposals I've seen so far for extending the spec's script preloading
 mechanisms fall into two categories:

 - provide some more 

Re: [whatwg] Script preloading

2013-07-22 Thread Kyle Simpson
 Do you have a link to your preload proposal?

My main `script preload` proposal (skip the first section of this LONG email, 
proposal starts at Summary: several paragraphs down):

http://lists.whatwg.org/htdig.cgi/whatwg-whatwg.org/2013-July/039973.html

Then proposal slightly amended here:

http://lists.whatwg.org/htdig.cgi/whatwg-whatwg.org/2013-July/039974.html



 Either way, I agree about the concern with onload. I personally have a
 hard time telling if it'll be confusing.
 
 Having the load event anytime we are done with a network request also
 seems beneficial. Rather than having most APIs use load whereas this
 would use preload.

FWIW, I believe script loaders, at least as I envision them, would use BOTH the 
`onpreload` AND the `onload` events, since marking a script as 
ready-to-execute, however that's done, is unlikely to be a synchronouse event, 
so the script loader would still want to listen for when it finished running 
(hopefully pretty soon after being told it's OK to run!? :)

I see the `onpreload` as similar in spirit to the non-standard and 
now-phased-out-as-of-IE11 `script.onreadystate` mechanism, which provided more 
detail about the status of a script as progressed from request to completion. 
`onpreload` just, to me, fills the spot of what semantically the word load 
meant, but since everyone knows load in the context of scripts means load 
and process/run, we can't lightly just change load.

If `onpreload` seemed to imply something too far outside the normal state 
progression of a script, it could be called `onfinishload` or `onfinishrequest` 
or something like that. In the `onreadystatechange` world, they called that 
state loaded, FWIW.



 Generally speaking load means loaded and processed. The
 'noexecute' flag would change what the and processed piece includes.

Understood.

I still think, though, that it's problematic to overload load, because as 
mentioned above, as a script loader, I'd want to know about both events 
(finished load and finished execution), not just a binary switch between 
one or the other. If load fired twice, that seems (potentially) awfully 
confusing. If load fired early (at load finish), and there was no more event 
for finished execution, script loaders would be quite hampered (at least as I 
envision architecting one) because they couldn't know if a script had really 
run yet or not, only that they asked it to be eligible to run.



 There are three opportunities to fire error stuff here:
 
 1. Failed network request
 2. Failed JS compilation
 3. Exception thrown from execution
 
 And there are two error reporting mechanisms in play
 
 A. Fire an error event on the script element.
 B. Fire the window.onerror callback (like an event, but not exactly the same).

Agreed. `window.onerror` serves fine case #3. What we don't seem to have as 
consistent cross-browser behavior, or even terribly well defined in the spec, 
is #1 and #2, especially #1. Various older browsers had different 
interpretations as to which network conditions constituted load complete or 
not.

Obviously, the 200 (and several other 2xx's) should be success. And I'd think 
it would be obvious that any of the 4xx and 5xx codes were error.

But perhaps it should just be: did the network request result in a non-empty 
payload?

Now, for #2, to my non-implementor eye, that seems pretty well definable too. 
But again, cross-browser mayhem was bad with this. IIRC, Opera fired the 
onerror in the case of bad compilation, but none of the others did. Or maybe it 
was vice versa. Been awhile since I looked specifically. Just for sure recall 
inconsistency here.



 1 and 2 seems like they could behave exactly the same for noexecute
 scripts as for normal scripts.

Yes, as long as all the spec makes it clear what the do's and don'ts here are, 
and everyone complies. :)



 I'm not sure if that includes firing
 both A and B in current browsers?

They do not seem to fire `window.onerror` in either #1 or #2 IIRC, but they do 
in #3.

If I could have it my way, I'd have all three errors firing on the 
script.onerror, and not involve window.onerror. The reason is because 
`window.onerror` is notoriously hijacked by various RUM libraries and such, to 
do remote logging of errors, so a script loader attaching to window.onerror and 
catch is not terribly reliable in my experience.

But I'm fine with whatever combination gives reliable and non-overlapping and 
non-gaping error handling coverage. :)



 3 presumably only triggers B currently for normal scripts?

AFAICT, yes.



 Indeed. Though we're only talking about the A mechanism about, right?

Correct. Although in an ideal world (for me), B would be more reliable, as 
noted above.



 I.e. the following would cause both a load event to be fired on the
 script, and window.onerror to be triggered?
 
 script src=data:text/plain,throw new Error();/script

Sure. Though as noted, script loaders may have limited utility of 
window.onerror when they run 

Re: [whatwg] Script preloading

2013-07-22 Thread Jonas Sicking
On Mon, Jul 22, 2013 at 4:01 PM, Kyle Simpson get...@gmail.com wrote:
 Do you have a link to your preload proposal?

 My main `script preload` proposal (skip the first section of this LONG 
 email, proposal starts at Summary: several paragraphs down):

 http://lists.whatwg.org/htdig.cgi/whatwg-whatwg.org/2013-July/039973.html

 Then proposal slightly amended here:

 http://lists.whatwg.org/htdig.cgi/whatwg-whatwg.org/2013-July/039974.html



 Either way, I agree about the concern with onload. I personally have a
 hard time telling if it'll be confusing.

 Having the load event anytime we are done with a network request also
 seems beneficial. Rather than having most APIs use load whereas this
 would use preload.

 FWIW, I believe script loaders, at least as I envision them, would use BOTH 
 the `onpreload` AND the `onload` events, since marking a script as 
 ready-to-execute, however that's done, is unlikely to be a synchronouse 
 event, so the script loader would still want to listen for when it finished 
 running (hopefully pretty soon after being told it's OK to run!? :)

In the noexecute proposal I believe that .execute() would be a
synchronous operation. Though we could change it to be an asynchronous
operation if that's desired. In which case I agree that we need some
sort of notification once the script has run.

 There are three opportunities to fire error stuff here:

 1. Failed network request
 2. Failed JS compilation
 3. Exception thrown from execution

 And there are two error reporting mechanisms in play

 A. Fire an error event on the script element.
 B. Fire the window.onerror callback (like an event, but not exactly the 
 same).

 Agreed. `window.onerror` serves fine case #3. What we don't seem to have as 
 consistent cross-browser behavior, or even terribly well defined in the spec, 
 is #1 and #2, especially #1. Various older browsers had different 
 interpretations as to which network conditions constituted load complete or 
 not.

 Obviously, the 200 (and several other 2xx's) should be success. And I'd think 
 it would be obvious that any of the 4xx and 5xx codes were error.

 But perhaps it should just be: did the network request result in a non-empty 
 payload?

 Now, for #2, to my non-implementor eye, that seems pretty well definable too. 
 But again, cross-browser mayhem was bad with this. IIRC, Opera fired the 
 onerror in the case of bad compilation, but none of the others did. Or maybe 
 it was vice versa. Been awhile since I looked specifically. Just for sure 
 recall inconsistency here.

Given that compatibility with existing content is the main issue here.
I think finding out where different UAs are consistent, and where they
are not is the first step here.

 I'm not sure if that includes firing
 both A and B in current browsers?

 They do not seem to fire `window.onerror` in either #1 or #2 IIRC, but they 
 do in #3.

 If I could have it my way, I'd have all three errors firing on the 
 script.onerror, and not involve window.onerror. The reason is because 
 `window.onerror` is notoriously hijacked by various RUM libraries and such, 
 to do remote logging of errors, so a script loader attaching to 
 window.onerror and catch is not terribly reliable in my experience.

Well, a script loader shouldn't really care about #3, should it? At
that point the script loader has fulfilled its responsibility.

Having #1 and #2 cause A to happen, and #3 cause B to happen, then I
think that's a pretty good state of affairs.


 Indeed. Though we're only talking about the A mechanism about, right?

 Correct. Although in an ideal world (for me), B would be more reliable, as 
 noted above.

I thought the above asked for A to be more reliable? Also, more
reliable probably is in the eye of the beholder. So rather than
talking about what's more reliable and less reliable it's better
to talk about specific behaviors.

 I.e. the following would cause both a load event to be fired on the
 script, and window.onerror to be triggered?

 script src=data:text/plain,throw new Error();/script

 Sure. Though as noted, script loaders may have limited utility of 
 window.onerror when they run in unfamiliar/hostile pages which already hijack 
 that error.

Ideally they can always call window.addEventListener(error, ...),
but apparently that doesn't always work. Not sure what specs say
though.

/ Jonas


Re: [whatwg] Script preloading

2013-07-18 Thread Kyle Simpson
About a week ago, I presented a set of code comparing the script 
dependencies=.. approach to the script preload approach, as far as creating 
generalized script loaders.

There were a number of concerns presented in those code snippets, and the 
surrounding discussions. I asked for input on the code and the issues raised.

Later in the thread, I also identified issues with needing to more robustly 
handle error recovery and it was suggested that Navigation Controller was a 
good candidate for partnering with script loading for this task. I asked for 
some code input in that respect as well.

AFAICT, the thread basically went dormant at roughly the same time.

I'm sure people are busy with plenty of other things, so I'm not trying to be 
annoying or impatient. But I would certainly like for the thread not to die, 
but to instead make productive progress.

If you have any feedback on the code comparisons I posted earlier 
(https://gist.github.com/getify/5976429) please do feel free to share.

Thanks!



--Kyle







Re: [whatwg] Script preloading: Browser Pre-compiled Scripts Cache?

2013-07-15 Thread Bruno Racineux
Taking about executing script as quickly as possible (threads from 1012
which I missed and tried to glanced through just get better educated about
previous conversations).

Wouldn't browsers be able to store pre-parsed/compiled' scripts in a
separate byte code cache,
with scripts promoted to the sticky cache based on their access frequency
(up to cache expiration)?
Say similarly to the way Fusion Drives or Seagate Adaptive Memory SSHDs
work.

i.e. Why do we have to keep re-parsing and re-evaluating the very same
scripts, especially CDN libraries and social apis largely shared among
websites, over and over?

If javascript can't be as truly fast a native apps:
http://sealedabstract.com/rants/why-mobile-web-apps-are-slow/
It seems that for frequently visited sites and frequently accessed libraries
across websites, the whole parse/evaluation time, could be cut 'partially',
yet very significantly, just like opcode does for php.
And make CDN libraries even more useful and relevant that way. Or is this
wildly nuts? In which case no need to answer.

Bruno



From:  Andy Davies dajdav...@gmail.com
Date:  Saturday, July 13, 2013 5:55 AM
To:  Bruno Racineux br...@hexanet.net, WHATWG List wha...@whatwg.org
Subject:  Re: [whatwg] Script preloading

 On 12 July 2013 01:25, Bruno Racineux br...@hexanet.net wrote:
 On browser preloading:
 
 There seems to an inherent conflict between 'indiscriminate' Pre-parsers/
 PreloadScanner and responsive design for mobile. Responsive designs
 mostly implies that everything needed for a full screen desktop is
 provided in markup to all devices.
 
 
 The pre-loader is a tradeoff, it's aiming to increase network utilisation by
 speculatively downloading resources it can discover.
 
 Some of the resources downloaded may be not be used but with good design and
 mobile first approaches hopefully this number can be minimised.
 
 Even if some unused resources get downloaded how much it matter?
 
 By starting the downloads earlier, connections will be opened sooner, and the
 TCP congestion window to grow sooner. Of course this has to be balanced
 against visitors who might be paying to download those unused bytes, and
 whether the unused resources are blocking something on the critical path from
 being downloaded (believe some preloaders can re-prioritise resources if they
 need them before the preloader has downloaded them)
 
 Although we talk about *the preloader*, it's worth remembering different
 browsers (and versions) have different preloading approaches - compare the
 connection view charts (at bottom of page) for www.channel4.com
 http://www.channel4.com  in Chrome, Firefox and IE10 and you'll see subtle
 differences:
 
 Chrome http://www.webpagetest.org/result/130713_0J_PC1/1/details/
 Firefox http://www.webpagetest.org/result/130713_P2_PBZ/1/details/
 IE10 http://www.webpagetest.org/result/130713_9A_PBW/1/details/
 
 
 
 Isn't the Pre-parsers/PreloadScanner's inability to take into account the
 display[none:yes] factor be a potential significant blow to 'mobile'
 performance.
 Use case: What if I have a set of images in an element set as
 display:none; only designated to be show on desktop or tablet screens and
 not on mobile phone?
 
 What if I have an inline script in that node?
 
 
 Isn't the PreloadScanner loading a lot more than I need, a problem here?
 
 Challenge with this approach is the browser has to build the render tree
 before it can decide whether to download a resource i.e. download HTML, parse
 it, build a DOM, download CSS, parse it, build CSSOM, then build render tree.
 
  
 
 In addition to the need to preload, with responsive design taken into
 consideration, and for lack of not being able to remove part of the body
 before the browser parses the document. I see an increasing potential need
 for the ability to indicate to the browser not to load selective assets
 before DOMReady and suppress such preload.
 
 
 The proposed lazyload attribute should help here
 https://dvcs.w3.org/hg/webperf/raw-file/tip/specs/ResourcePriorities/Overview.
 html 
 
 Yoav Weiss has raised the idea of being able to use media queries with scripts
 and other resources too.
 
 Responsive design is young, I think we still have a lot to learn and it's
 going to take a while before we really understand what features we need.
 
 Cheers
 
 Andy




Re: [whatwg] Script preloading: Browser Pre-compiled Scripts Cache?

2013-07-15 Thread Yoav Weiss
On Mon, Jul 15, 2013 at 9:42 AM, Bruno Racineux br...@hexanet.net wrote:

 Taking about executing script as quickly as possible (threads from 1012
 which I missed and tried to glanced through just get better educated about
 previous conversations).

 Wouldn't browsers be able to store pre-parsed/compiled' scripts in a
 separate byte code cache,
 with scripts promoted to the sticky cache based on their access frequency
 (up to cache expiration)?
 Say similarly to the way Fusion Drives or Seagate Adaptive Memory SSHDs
 work.

 i.e. Why do we have to keep re-parsing and re-evaluating the very same
 scripts, especially CDN libraries and social apis largely shared among
 websites, over and over?



I've raised some similar concerns and made a possibly unrealistic proposal
to resolve them at the Extensible Web mailing list[1]
I believe some form of JS code installation so that it can be used across
sites would provide a major performance boost, if it can be done in a
secure way, without throwing URLs under the bus. It will enable users to
avoid re-downloading frameworks and polyfills again and again for each site
they visit, and will also enable browsers to optimize these frameworks'
generated machine code.

[1] http://lists.w3.org/Archives/Public/public-nextweb/2013Jun/0050.html


Re: [whatwg] Script preloading: Browser Pre-compiled Scripts Cache?

2013-07-15 Thread Boris Zbarsky

On 7/15/13 3:42 AM, Bruno Racineux wrote:

Wouldn't browsers be able to store pre-parsed/compiled' scripts in a
separate byte code cache,


You mean like https://bugzilla.mozilla.org/show_bug.cgi?id=679942 ?

There's some discussion in there about whether this is a worthwhile 
optimization with modern JS engines, which feature lazy compilation and 
even lazy parsing to a large extent  Measurement is needed of the 
various pieces discussed in 
https://bugzilla.mozilla.org/show_bug.cgi?id=679942#c6 and 
https://bugzilla.mozilla.org/show_bug.cgi?id=679942#c7.


In either case, note that there is already caching of this sort to some 
extent in SpiderMonkey; see 
https://bugzilla.mozilla.org/show_bug.cgi?id=883154 which is fixed. 
Note that in the context of that bug a script is what you probably 
think of as a function body: that's the fundamental unit of 
compilation in SpiderMonkey now that we do lazy compilation.



i.e. Why do we have to keep re-parsing and re-evaluating the very same
scripts, especially CDN libraries and social apis largely shared among
websites, over and over?


The re-evaluating is because evaluation has little things like 
side-effects.  ;)



the whole parse/evaluation time, could be cut 'partially', yet very 
significantly


Some hard data would be useful here, as I said above.

-Boris


Re: [whatwg] Script preloading, ES6 modules

2013-07-15 Thread Kornel Lesiński


ES6 modules[1] have a script loader API[2].

That API is pretty powerful to the point it can emulate other script  
loaders, load files that are not ES6 modules, and even load text files  
that aren't JS (intended for compilation of coffeescript-like languages,  
but could be abused for anything):


https://gist.github.com/wycats/51c96e3adcdb3a68cbc3#using-existing-libraries-as-modules


There's a very high overlap between module dependencies and script  
dependencies proposal. I think at very least it would be useful to define  
script dependencies in terms of ES6 modules, or even abandon markup  
solution to avoid duplicating features.



ES6 modules however do not solve the performance problem. In fact they  
would benefit from UA having a list of all dependencies up front  
(otherwise file's dependencies can only be discovered after that file is  
loaded, which costs as many RTTs as the height of the dependency tree).


So I think that eventually ES6 modules + link[rel=subresource] could be  
the answer. The link would expose URLs to (pre)load for performance, but  
modules would handle actual loading/execution for flexibility and  
reliability.


--
regards, Kornel

[1] http://wiki.ecmascript.org/doku.php?id=harmony:modules
[2] http://wiki.ecmascript.org/doku.php?id=harmony:module_loaders


Re: [whatwg] Script preloading: Browser Pre-compiled Scripts Cache?

2013-07-15 Thread Bruno Racineux

On 7/15/13 6:12 AM, Yoav Weiss y...@yoav.ws wrote:

On Mon, Jul 15, 2013 at 9:42 AM, Bruno Racineux br...@hexanet.net wrote:

 Taking about executing script as quickly as possible (threads from
1012
 which I missed and tried to glanced through just get better educated
about
 previous conversations).

 Wouldn't browsers be able to store pre-parsed/compiled' scripts in a
 separate byte code cache,
 with scripts promoted to the sticky cache based on their access
frequency
 (up to cache expiration)?
 Say similarly to the way Fusion Drives or Seagate Adaptive Memory SSHDs
 work.

 i.e. Why do we have to keep re-parsing and re-evaluating the very same
 scripts, especially CDN libraries and social apis largely shared among
 websites, over and over?



I've raised some similar concerns and made a possibly unrealistic proposal
to resolve them at the Extensible Web mailing list[1]
I believe some form of JS code installation so that it can be used
across
sites would provide a major performance boost, if it can be done in a
secure way, without throwing URLs under the bus. It will enable users to
avoid re-downloading frameworks and polyfills again and again for each
site
they visit, and will also enable browsers to optimize these frameworks'
generated machine code.

[1] http://lists.w3.org/Archives/Public/public-nextweb/2013Jun/0050.html

It goes beyond frameworks if based on pure 'access frequency'.

For example, a site backend you use daily or you favorite web app would be
also benefit.
Including the G+, Twitter and Facebook site's scripts, Map APIs, Google
News, or whatever you access most frequently from your machine.

And I am not thinking 'installation' or 'packages' in the sense that you
expressed.
That was my early thinking too, but say Google providing jQuery and all
the hosted APIs preloaded in Chrome seems too difficult to handle, due to
versioning aspects as well as limited scope.

To be truly worth, it needs to be broad, based on access frequency by urls.

Browsers already have a way to tell what your top sites are. Doing it for
scripts doesn't seem too far fetched from there. And top sites can be used
as additional priority factors.




Re: [whatwg] Script preloading: Browser Pre-compiled Scripts Cache?

2013-07-15 Thread Yoav Weiss

 It goes beyond frameworks if based on pure 'access frequency'.

 For example, a site backend you use daily or you favorite web app would be
 also benefit.
 Including the G+, Twitter and Facebook site's scripts, Map APIs, Google
 News, or whatever you access most frequently from your machine.


For scripts that are always delivered through a single URL, no standard
change is needed in order to make this optimization happen. As Boris
pointed out, this is already done in Firefox [1]


 And I am not thinking 'installation' or 'packages' in the sense that you
 expressed.
 That was my early thinking too, but say Google providing jQuery and all
 the hosted APIs preloaded in Chrome seems too difficult to handle, due to
 versioning aspects as well as limited scope.

 To be truly worth, it needs to be broad, based on access frequency by urls.


Unfortunately, for framework caching, using only URLs for caching purposes
have proven to be insufficient, resulting in very little code reuse across
sites, because of multiple CDNS and versioning [2]


[1] https://bugzilla.mozilla.org/show_bug.cgi?id=883154
[2] http://statichtml.com/2011/google-ajax-libraries-caching.html


Re: [whatwg] Script preloading: Browser Pre-compiled Scripts Cache?

2013-07-15 Thread Bruno Racineux


On 7/15/13 3:02 PM, Yoav Weiss y...@yoav.ws wrote:


 It goes beyond frameworks if based on pure 'access frequency'.

 For example, a site backend you use daily or you favorite web app would
be
 also benefit.
 Including the G+, Twitter and Facebook site's scripts, Map APIs, Google
 News, or whatever you access most frequently from your machine.


For scripts that are always delivered through a single URL, no standard
change is needed in order to make this optimization happen. As Boris
pointed out, this is already done in Firefox [1]
Nods, I think I get what Boris said for the most part, reading the links
afterwards.



 And I am not thinking 'installation' or 'packages' in the sense that you
 expressed.
 That was my early thinking too, but say Google providing jQuery and all
 the hosted APIs preloaded in Chrome seems too difficult to handle, due
to
 versioning aspects as well as limited scope.

 To be truly worth, it needs to be broad, based on access frequency by
urls.


Unfortunately, for framework caching, using only URLs for caching purposes
have proven to be insufficient, resulting in very little code reuse across
sites, because of multiple CDNS and versioning [2]

Well just to be clear, my suggested approach rely on URL 'access
frequency' beyond browser sessions, and beyond libraries.
i.e. The compiled cache only gets recycled for frequently accessed scripts.

If the most frequently accessed scripts turn out to be jquery 1.8.2 and
1.10.2 and 2.0.3, then all three are cached of even 10 versions is that's
the case.
Then possibly put to disk on browser shutdown and back to memory on start.
And say reserve a sticky cache of up to XMB of ram for those.
They oviously have to be re-cached as per given cache expiration.

But in that it doesn't really care about a particular library, it's
popularity or even it's code. It's code agnostics and mostly concerned
that the script you access every day are pre-compiled and never
re-downloaded until cache expiry. That's the idea.


[1] https://bugzilla.mozilla.org/show_bug.cgi?id=883154

The outline there suggest: - When compiling a lazy script with no inner
functions, do a table lookup for a script with the same source location
(filename, lineno, column, source begin/end

I am no going that far with the overhead. My suggestion is to be only
interested in the unique URL hash (not line no, column, or source
begin/end). Just how many times that script has been accessed in the last
day, week or month.

Perhaps I am wrongly thinking of whole scripts vs thinking of script as
a function body like Boris suggested. I am not a browser-dev or c coder,
and only relying on php opcode as limited basis for my though process...

Or the fundamental unit of compilation for JS is incompatible with my
approach. IDK

[2] http://statichtml.com/2011/google-ajax-libraries-caching.html





Re: [whatwg] Script preloading: Browser Pre-compiled Scripts Cache?

2013-07-15 Thread Boris Zbarsky

On 7/15/13 7:28 PM, Bruno Racineux wrote:

The outline there suggest: - When compiling a lazy script with no inner
functions, do a table lookup for a script with the same source location
(filename, lineno, column, source begin/end


So just to be clear: that bug is talking about script in the sense 
that SpiderMonkey thinks of it, which again is either a toplevel script 
or a function body.


The above lookup is basically an optimization: once the lookup is done 
the result of the lookup is a pair: script chars and compiled code.  The 
script chars are then compared to the chars of the script that needs to 
be compiled, and if those match the compiled code is used.  The reason 
for factoring in lineno and column is to minimize the number of chars 
compares that need to be done (recall that script here is a function 
body in many cases, and there are lots of those on a single line of a 
single file in a typical minified script).



I am no going that far with the overhead. My suggestion is to be only
interested in the unique URL hash (not line no, column, or source
begin/end). Just how many times that script has been accessed in the last
day, week or month.


Sure, but then what gets done with that information?

Current UAs for the most part do the following, for a whole script:

1)  Do a fast tokenization pass to catch syntax errors and determine 
function boundaries.


2)  Compile and run the toplevel parts of the script.

Functions are then compiled the first time they're actually called. 
Turns out your typical web page includes lots of functions (mostly in 
libraries) that it never calls.


I assume the proposal is to cache, for a given URL, not just the string 
for the script but also the results of the initial syntax-check pass and 
whatever things we compiled, right?   That might be worth it, as I said, 
but needs careful measurement: to the extent that the storage is slow 
and the CPU is fast and the compiler is fast and simple (which the 
first-pass compiler typically tries to be) recompiling may be faster 
than deserializing a compiled representation.



Or the fundamental unit of compilation for JS


It's only the fundamental unit because of the above observation that 
many functions never get called.


-Boris


Re: [whatwg] Script preloading, optional dependencies

2013-07-14 Thread Kornel Lesiński

On Fri, 12 Jul 2013 21:20:57 +0100, Kyle Simpson get...@gmail.com wrote:

So, just to clarify, `script dependencies=…` waiting on some other  
script tag is ONLY waiting on that script tag loading to have some  
sort of positive network result, whether that be a 2xx, 3xx, 4xx, or  
5xx, and it cares not whether the script in question actually loaded,  
nor whether it fired its `onerror` event? Do I have that correct?


What should happen is an interesting question.

If execution continued when dependency fails to load/parse, then later  
scripts could try to recover/use fallback/run with reduced functionality  
(e.g. if jQuery plugin for fancy animations fails to load the application  
can disable fancy animations and run anyway).


OTOH aborting execution of the rest of the dependency chain is probably  
what most developers expect, and it often makes sense as most scripts  
without dependencies met will fail.



So maybe a concept of optional dependency would be useful?

e.g. error handler could signal somehow that execution should continue:

script id=fancy-animations src=//flaky.cdn/js onerror=return  
false; /


or there could be a microsyntax in dependencies:

script dependencies=fancy-animations? required-stuff /

or:

script id=fancy-animations-cdn src=//flaky.cdn/js /
script id=fancy-animations-local src=/fancy-animations-copy.js /
script id=nothing /
script dependencies=(fancy-animations-cdn or fancy-animations-local  
or nothing) required-stuff /


--
regards, Kornel


Re: [whatwg] Script preloading, non-script dependencies

2013-07-14 Thread Kornel Lesiński

On Tue, 09 Jul 2013 20:39:45 +0100, Ian Hickson i...@hixie.ch wrote:


Would something like this, based on proposals from a variety of people in
the past, work for your needs?

1. Add a dependencies attribute to script that can point to other
   scripts to indicate that execution of this script should be delayed
   until all other scripts that are (a) earlier in the tree order and (b)
   identified by this attribute have executed.

 script id=jquery src=jquery.js async/script
 script id=shims src=shims.js async/script
 script dependencies=shims jquery src=myscript.js  
async/script


On a basic level it's similar to JS async module definition pattern  
(https://github.com/amdjs/amdjs-api/wiki/AMD), which is good, but may be  
insufficient.


require.js (AMD implementation) has useful concept of loader plugins for  
dependencies (https://github.com/millermedeiros/requirejs-plugins).
A plugin is basically a function that is told to load a path and calls  
callback when it's done.


It solves two problems:

1. not all dependencies are JS files, e.g. authors use plugins to load  
template files, JSON, images, etc.


script dependencies=load_template('view.hbs') src=view.js
script
function load_template(url, callback) {
fetch(url).then(callback);  // in require.js result is  
directly passed to the module.

}
/script

2. not all dependencies are usefully satisfied immediately after their JS  
file is loaded, e.g. some libraries may need asynchronous initialization.  
In require.js it's possible to wrap initialization in a plugin that will  
wait until it's done, so modules dependent on it can start using  
initialized library right away.


script id=load-library src=library.js /
script dependencies=load-library
function library_initialized(callback) {
$library.on('ready', callback)
}
/script
script dependencies=library_initialized() src=use-it-now.js/


Another common kind of dependency scripts have is presence of certain  
element in the DOM, e.g. `dropdown-menu.js` may require `nav id=menu`  
to be in the document _and_ have its content fully parsed before the  
script can run.


So, could script dependencies point to non-script elements?

script dependencies=menu src=dropdown-menu.js/
nav id=menu
!-- script not run yet --
ul.../ul
/nav
!-- script run at this point --

It would be nice if the browser also deferred rendering of the element  
until scripts that depend on it are run to avoid Flash of Unbehaviored  
Content (e.g. elements listed in dependencies have display:none until  
scripts are run).


--
regards, Kornel


Re: [whatwg] Script preloading

2013-07-14 Thread Kyle Simpson
 So maybe a concept of optional dependency would be useful?

 1. not all dependencies are JS files, e.g. authors use plugins to load  
 template files, JSON, images, etc.

 2. not all dependencies are usefully satisfied immediately after their JS  
 file is loaded, e.g. some libraries may need asynchronous initialization.  

These are relevant statements of other use-cases that are common.

I just want to point out that my script preload proposal easily handles (via 
a script-based script loader, not markup-only) both of these use-case 
variations, no matter how deep you chase their rabbit holes.

In my proposal, the script loader (or module loader, or whatever) is fully in 
control of when the next waiting script is told that it's eligible to execute, 
so it can accept any arbitrary amount of complexity into its configuration for 
how to decide that it's OK to proceed from A to B.

For example, if, in the execution of A, A registers that it needs C, then B 
won't auto-run just because A finishes. If C is not a script, but is a template 
or stylesheet or series of images or Ajax call for some data or whatever... 
none of that complication affects the script preload mechanism whatsoever. It 
simply leaves B preloaded, paitiently waiting around until it's told that its 
dependencies are fulfilled, and the script loader can wait as long as it needs 
to until A and anything A needs (C, C*) are loaded and processed.

In the script dependencies proposals and variations, we have to follow the 
rabbit trail of inventing micro-syntaxes or other attribute complexities to 
handle these markup expressions of dependency that are not as 
trivial/simplistic as a prior completed network connection and, if applicable, 
parsing and processing, as you're seeing in Kornel's two messages.

*
Of course, I don't share the same mindset of some here that any markup-only 
solution we could invent, no matter how complex or intricate or involved, is 
better than a script-based equivalent.
*

To me, markup should be able to handle the majority case(s), and minority cases 
(while important) should be handled in script-based loading. script preload 
(including the markup extension I suggested) does exactly that: it handles 
basic preload/dependency annotation with markup-only, and it provides the full 
preload-defer-execute mechanism to the script-based loader for handling 
*everything* else you can dream up (AND you can mix-n-match).

By contrast, the prior simple statement of script dependencies=... proposal 
(without Kornel's extensions) handles basic preload/dependency annotation in 
markup-only, but then the other more complex use-cases appear to have to be 
filled by pulling in and weaving together other (proposed) mechanisms like 
Navigation Controller.

I'm not saying that's a bad option, but we need to be able to compare what the 
script-based approach is going to look in both scenarios, and see which one is 
more suitable/practical/desireable.



--Kyle












Re: [whatwg] Script preloading

2013-07-14 Thread Garrett Smith
On 7/10/13, Jake Archibald jaffathec...@gmail.com wrote:
 On 9 July 2013 22:31, Garrett Smith dhtmlkitc...@gmail.com wrote:

 On 7/9/13, Ian Hickson i...@hixie.ch wrote:script id=jquery
 src=jquery.js async/script
   script id=shims src=shims.js async/script
   script dependencies=shims jquery src=myscript.js
 async/script
 

 Why limit depends to be used by only scripts to refer only to other
 scripts?

 If you put link depends=idref on style then stylesheet evaluation
 could be deferred, too.


 I like this idea and want to start a family with it.

Sorry, I didn't get that.

A 'depends' attribute would work like the 'for' attribute of SCRIPT
element in older versions MSIE, with a difference: if (any of) the
resource(s) has a fetching algorithm associated, the event does not
fire until that has successfully completed.

Also, depends=[DomTokenList] could be, instead of depends=IDREF
-- 
Garrett
Twitter: @xkit
personx.tumblr.com


Re: [whatwg] Script preloading

2013-07-14 Thread Bruno Racineux


On 7/13/13 5:55 AM, Andy Davies dajdav...@gmail.com wrote:

On 12 July 2013 01:25, Bruno Racineux br...@hexanet.net wrote:

 On browser preloading:

 There seems to an inherent conflict between 'indiscriminate'
Pre-parsers/
 PreloadScanner and responsive design for mobile. Responsive designs
 mostly implies that everything needed for a full screen desktop is
 provided in markup to all devices.


The pre-loader is a tradeoff, it's aiming to increase network utilisation
by speculatively downloading resources it can discover.

Some of the resources downloaded may be not be used but with good design
and mobile first approaches hopefully this number can be minimised.

Even if some unused resources get downloaded how much it matter?

By starting the downloads earlier, connections will be opened sooner, and
the TCP congestion window to grow sooner. Of course this has to be
balanced
against visitors who might be paying to download those unused bytes, and
whether the unused resources are blocking something on the critical path
from being downloaded (believe some preloaders can re-prioritise resources
if they need them before the preloader has downloaded them)

Although we talk about *the preloader*, it's worth remembering different
browsers (and versions) have different preloading approaches - compare the
connection view charts (at bottom of page) for www.channel4.com in Chrome,
Firefox and IE10 and you'll see subtle differences:

Chrome http://www.webpagetest.org/result/130713_0J_PC1/1/details/
Firefox http://www.webpagetest.org/result/130713_P2_PBZ/1/details/
IE10 http://www.webpagetest.org/result/130713_9A_PBW/1/details/



 Isn't the Pre-parsers/PreloadScanner's inability to take into account
the
 display[none:yes] factor be a potential significant blow to 'mobile'
 performance.

Use case: What if I have a set of images in an element set as
 display:none; only designated to be show on desktop or tablet screens
and
 not on mobile phone?

 What if I have an inline script in that node?


 Isn't the PreloadScanner loading a lot more than I need, a problem here?


Challenge with this approach is the browser has to build the render tree
before it can decide whether to download a resource i.e. download HTML,
parse it, build a DOM, download CSS, parse it, build CSSOM, then build
render tree.
Well the crazy idea I had in mind here, is more of a scenario like:

Download and parse HEAD, my script, download BODY, parse BODY, build a
DOM, let me interact with the DOM with JS first, PreloadScanner, parse
CSS, build CSSOM, then build render tree... But it's javascript only and a
whole new level of DOMReady approach :)




 In addition to the need to preload, with responsive design taken into
 consideration, and for lack of not being able to remove part of the
body
 before the browser parses the document. I see an increasing potential
need
 for the ability to indicate to the browser not to load selective assets
 before DOMReady and suppress such preload.


The proposed lazyload attribute should help here
https://dvcs.w3.org/hg/webperf/raw-file/tip/specs/ResourcePriorities/Overv
iew.html

Thanks for pointing that out. Interesting solution.

It's actually quite on topic with this thread. Noting that the 'lazyload'
proposal, which tries to do the opposite of preload, somewhat also
introduces a notion of dependencies with scripts and other elements via a
simple priority mechanism.

That is, as per current specs:
 script src=jquery-plugin1.js lazyload/script

 script src=jquery-plugin2.js lazyload/script

 script src=jquery.js/script


It implies that I want to load my plugins for later use, they depend on
jquery which will load and execute first, and the dependent scripts do not
delay the load of the document.

Now it'd be interesting to see how 'lazyload' deals with async or
async=false which is not fully specified. Or wether 'deferred' scripts
execution precedes 'lazyload' scripts or not. It a bit unclear there.

But in a sense 'lazyload' can defer a stylesheet evaluation like Garrett
suggested.



And 'lazyload' has implications with such 'dependency' or 'whenneeded'
markup. It gets complicated.


Yoav Weiss has raised the idea of being able to use media queries with
scripts and other resources too.
Nods, raising the idea makes sense.

Responsive design is young, I think we still have a lot to learn and it's
going to take a while before we really understand what features we need.

Cheers

Andy




Re: [whatwg] Script preloading

2013-07-13 Thread Bruno Racineux
Nobody should be arguing about 'pet projects' or 'ignorance' here, it's
really uncalled for. Characterizing strong counter arguments or strong
views as 'attacks' is also unnecessary.

May I remind you Alex that this thread's request for feedback started with
two simple questions: Would something like this, based on proposals from
a variety of people in the past, work for your needs?

Is there something this doesn't handle which it would need to handle?

Ian even implied not quite understanding these requirements with the
proposal.

As such, refusing to considerate any new requirements, or shooting down
strong critics, as EYE-WATERING-LENGTH as they may be, AND/OR suggesting
that Ian's early proposal is an already foolproof (completely thought
through solution) seems a bit misplaced. If my English as a second
language serves me well, that's not quite the initial premise of this
thread and its original questions.

Anyway, I just want to make additional arguments as best I can with a
use-case below; in support to Kyle Simpson's apparently struggle to try
and get part of his points across, along with one of his remark; and a
more direct attempt to answer Ian's questions.


On 7/12/13 8:31 AM, Kyle Simpson get...@gmail.com wrote:

It'd be great if it just could automatically re-try or fallback to
another URL. Yeah, that sounds cool. Sure, will do.

Re-try or fallback is/was a first requirement for me, before even
considered using a CDN for jQuery. The consideration for such ability for
a reliable fallback with script.fail event is quite basic.

To demonstrate than MANY people care about that. This page has been viewed
over 6 times with high reputation scores:
http://stackoverflow.com/questions/1014203/best-way-to-use-googles-hosted-j
query-but-fall-back-to-my-hosted-library-on-go

Yet, that thread offers a fallback that may not even work depending on
DNS/network conditions. Most people blindly assume it will. But the fact
is, it doesn't.
As a minimum you are looking at a 10-30sec delay. i.e. Page considered
dead! Visitor likely gone...

Fallback(s) in a cloud-centric environment is moot. Right now we have
nothing to prevent a page from being partially or fully down due to
external js failures.

Let's take this premise.
I am gonna use Google's CDN because it's recommended and improve
performance.
And CNDJS for the shim library because it's convenient and fast. So:

script id=jquery src=googleCDN/jquery.js async/script
 script id=shims src=CDNJS/shims.js async/script
 script dependencies=shims jquery src=mysite/myscript.js
async/script


Ok, so I rely on the browser to automatically load dependencies for me
right?

Use case:
Either googleCDN's or CDNJS fail for whatever reason.
What does the browser do?
Try one more time, report me an error?
Let me down with a failed load all together? My one time visitor, which I
also happen to have payed Google Adwords for the click, cannot visit my
site. Wasted $5 bucks? Lost a potential sale?

So how does this proposal handle such situation, or better put: gives me
control to determine what has loaded or wether it's going to succeed in
loading at all?

Is it not sufficient in this regard, and does not propose to handle
fallbacks.

Also using scripts id(s) have the problem of possible conflict with
other elements using duplicate ids in the document, in an unpredictable
fashion (unique identifier must). I.e. IDs can't be used. I actually faced
that conflict myself early on...
Nor can 'class', nor can 'name' (which I use but it only works when used
dynamically, and not allowed officially as markup). That would leave you
with 'title' or the need for a new attribute. And no easy/fast
document.getElementById('myscript') possible.


Overall, the ex2-getify.js's approach to address control, failures,
execution, and fallback matters is a better way to deal with this, or at
least simpler to comprehend for a developer at large, in my view.

https://gist.github.com/getify/5976429#file-ex2-getify-js

I personally wouldn't go as far as 'script.error', I think that's maybe
pushing it. Although a richer script.readyState(s) type protocol could
surely benefit from it.


But having such states as 'waiting', 'failed', 'loading' and 'loaded' are
needed when it comes to 'guaranteed' pre-loading/loading. script.onload
being rather insufficient.

If link[rel=subresource] is adopted and works in comprehensive way with
possible states/events of its own. The need to pause execution is not
necessarily a requirement here. But if it's to use a basic
link[rel=subresource] and implement whenneeded/markNeeded() on top of it,
both without any notion of 'waiting', 'failed', 'loading' or 'loaded', to
fully accomplish one goal, it feels redundant and still missing critical
components for reliability sake. I for one wouldn't really foresee myself
using whenneeded/markNeeded() anyway.

While existing method for delayed parsing/execution work and are
supported. They are still considered a hack. And as 

Re: [whatwg] Script preloading

2013-07-13 Thread Andy Davies
On 12 July 2013 01:25, Bruno Racineux br...@hexanet.net wrote:

 On browser preloading:

 There seems to an inherent conflict between 'indiscriminate' Pre-parsers/
 PreloadScanner and responsive design for mobile. Responsive designs
 mostly implies that everything needed for a full screen desktop is
 provided in markup to all devices.


The pre-loader is a tradeoff, it's aiming to increase network utilisation
by speculatively downloading resources it can discover.

Some of the resources downloaded may be not be used but with good design
and mobile first approaches hopefully this number can be minimised.

Even if some unused resources get downloaded how much it matter?

By starting the downloads earlier, connections will be opened sooner, and
the TCP congestion window to grow sooner. Of course this has to be balanced
against visitors who might be paying to download those unused bytes, and
whether the unused resources are blocking something on the critical path
from being downloaded (believe some preloaders can re-prioritise resources
if they need them before the preloader has downloaded them)

Although we talk about *the preloader*, it's worth remembering different
browsers (and versions) have different preloading approaches - compare the
connection view charts (at bottom of page) for www.channel4.com in Chrome,
Firefox and IE10 and you'll see subtle differences:

Chrome http://www.webpagetest.org/result/130713_0J_PC1/1/details/
Firefox http://www.webpagetest.org/result/130713_P2_PBZ/1/details/
IE10 http://www.webpagetest.org/result/130713_9A_PBW/1/details/



 Isn't the Pre-parsers/PreloadScanner's inability to take into account the
 display[none:yes] factor be a potential significant blow to 'mobile'
 performance.

Use case: What if I have a set of images in an element set as
 display:none; only designated to be show on desktop or tablet screens and
 not on mobile phone?

 What if I have an inline script in that node?


 Isn't the PreloadScanner loading a lot more than I need, a problem here?


Challenge with this approach is the browser has to build the render tree
before it can decide whether to download a resource i.e. download HTML,
parse it, build a DOM, download CSS, parse it, build CSSOM, then build
render tree.




 In addition to the need to preload, with responsive design taken into
 consideration, and for lack of not being able to remove part of the body
 before the browser parses the document. I see an increasing potential need
 for the ability to indicate to the browser not to load selective assets
 before DOMReady and suppress such preload.


The proposed lazyload attribute should help here
https://dvcs.w3.org/hg/webperf/raw-file/tip/specs/ResourcePriorities/Overview.html


Yoav Weiss has raised the idea of being able to use media queries with
scripts and other resources too.

Responsive design is young, I think we still have a lot to learn and it's
going to take a while before we really understand what features we need.

Cheers

Andy


Re: [whatwg] Script preloading

2013-07-12 Thread Bruno Racineux


On 7/11/13 6:00 AM, Jake Archibald jaffathec...@gmail.com wrote:




link rel=subresourceŠ almost 50% of scripts Š sent without proper
caching headers. If the browser is doing what it should do, it won't
cache those

This is not how link[rel=subresource] should work, the first request
for the subresource should pick up from where the link left off. If it
doesn't do that, let's fix it, then we get the feature working
properly for more than just scripts.
6. Use-case: I want to preload a script which is hosted somewhere that I
don't control caching headers, and to my dismay, I discover that they
are serving the script with incorrect/busted/missing caching headers. If
I use a cache-preload technique, it will fail to work as I had hoped. I
will pay the double-download penalty because the browser didn't actually
cache it the first time, and my user will pay the extra UX penalty of
having to wait longer for the second load, when my whole goal was to
remove that UX visible delay.

Use-case: (as above) I should be able to preload scripts served by a
third party with no cache headers

link[rel=subresource] has you covered and should be fixed if it isn't
working.

Kyle, on the caching I don't think its legit to cache a file that is not
sent to be cached, as bad or involuntary as it might be from the provider.



Jake, now I that I am more familiarized with link[rel=subresource] it
seems to indeed solve some the preloading without executing side of
things. And good for performance especially if they can be provided in the
HEADER.

Is there a benefit from having a 'subresource' in the HEADER with the same
blocking script in the head?

I am thinking jQuery and the main css for example. It seems like css and
jQuery could be partially or even already available by the time /head is
received. Assuming the HEADER is received and processed before the head
start downloading (I am mot sure if this is the case).


It'd be useful that a broader scope of link[rel=subresource] be specified,
or pre-formalized. There is little documentation other than the chromium
page right now, and no reference on:
http://wiki.whatwg.org/wiki/RelExtensions, where it has a proposal status.

A couple question I would have right about it, based on its current
implementation are:

Can multiple subresource(s) be specified in the HEADER?


If specified in the HEADER can the Request send 'current' cookies?

Does the Response of a link[rel=subresource] from the HEADER set cookies
normally?

One issue, I am seeing right now in Opera/Blink is that the script seem to
download twice if requested with XHR. That shouldn't be.
 




Re: [whatwg] Script preloading

2013-07-12 Thread Andy Davies
On 9 July 2013 20:39, Ian Hickson i...@hixie.ch wrote:


 A topic that regularly comes up is script loading.

 I sent an e-mail responding to related feedback last year, though it
 didn't get any replies to the script loading parts of it:


 http://lists.w3.org/Archives/Public/public-whatwg-archive/2012Dec/0221.html


Pretty sure the cases I mentioned are met by the proposed lazyload
attribute


Re: [whatwg] Script preloading

2013-07-12 Thread Kyle Simpson
 Ok, and I'm saying they shouldn't be asking LABjs to handle it, they should 
 be asking the devtools teams at browser vendors to give them ways to deal 
 with it. You're not going to be able to pause execution for code, implement 
 future breakpoints, or debug root causes for this sort of thing well from 
 script. You can do SOMETHING, but not with the fidelity that devtools can.

I'm not sure why you keep focusing on this being a devtools centric question, 
because I think you're missing the point.

The developers that are asking for these features from LABjs are NOT asking for 
the capability to debug what's going on with failed loads while testing their 
app in their development environment. IF what they're trying to do is diagnose 
and fix such failed loads while developing their app, then certainly that would 
squarely be a devtools type of task.

LABjs also has a debug-build available, and it has certain extra tracing going 
on inside it when used, that aids developers in understanding, from its 
perspective, what is going on as things proceed through loading. That debug 
mode, in addition to whatever great devtools that exist or will exist, are all 
fantastic ways for developers to work on and fix problems.

***
But all that is ENTIRELY ORTHGONAL to what the developers are actually 
presently asking from LABjs.
***

They are asking, repeatedly, for the ability to have logic deployed in their 
*production* builds, which sits in front of end users which have no knowledge 
of or relation to any developer tools in whatever browser they use. Certainly, 
these developers are not interested in whether or not their end-users happen to 
be in a browser that has devtools, because end users don't care about devtools, 
and the developers who do care aren't actually using the user's browser anyway.

At this point, whether or not a browser has certain devtools is entirely 
irrelevant to what the developer wants from LABjs.

What seems to be their mindset and internal narrative is this: 

OK, no matter how good we are at figuring out how to build a bug-free app, we 
rely on third-party external resources that we don't control. We cannot 
guarantee that our request for 'jquery.js' from the Google CDN will actually 
work. It should work. It usually works. But it doesn't always work. Sometimes 
Google goes down. Sometimes the DNS lookup fails. Sometimes a proxy server 
misbehaves. Sh$$ happens. SO! We'll just accept that fact. We look at our RUM 
logs and we see that about 2% of our users experience one of these dead page 
loads. But, hey, I've got an idea, how about we try to write code into our 
production code which detects when something like that happens, and tries to 
gracefully recover, if possible, to maybe reduce the 2% down to 1%. Yeah, 
that's a good idea. How do we do that? Oh, I know! We're already using a script 
loader. Let's have that script loader tell us when `script.onerror` fires, 
which tells us that a script load failed (right!?!?), and we'll just re-request 
it from a fallback location on our own CDN. Sounds like a plan. Can you file a 
feature request at LABjs for them to expose when `script.onerror` fires? It'd 
be great if it just could automatically re-try or fallback to another URL. 
Yeah, that sounds cool. Sure, will do.

I understand clearly at this point that you don't agree with their mindset. I 
understand you think their desire is misguided. I admit sometimes I am 
skeptical of the efficacy of such efforts.

But respectfully speaking, your opinion is not the only one that matters here.

Who are we to tell some in-good-faith developer that they are objectively WRONG 
to hope their script loader could not only LOAD scripts but RELOAD or ALTLOAD 
scripts. Think about the conceptual and semantic there. It's a pretty sensible 
expectation for most non-browser-author devs.



 We'll be able to do this from the Navigation Controller: 
 https://github.com/slightlyoff/NavigationController/blob/master/explainer.md

Never heard of it before. Thanks for the link.

But I don't see how the idea that this may (likely) happen (someday) 
automatically moots the discussion at hand. For you to fairly exercise some 
sort of veto vote over what we discuss, which it seems like you're trying to 
do, you've gotta come to the table with some real tangible thing that's 
standardized (or clearly headed that way) and ready to evaluate for fitness to 
the use-cases.

I glanced through (it's long, haven't digested it yet) and didn't immediately 
see a section called RETRYING AND FALLBACK LOADING. :)

I don't see an MDN page entry for `Navigation Controller`. I can't find 
Navigation Controller on http://caniuse.com yet. So far, the only google 
result I've found for it is your writeup. So having only seen it for a few 
moments as of the writing of this email, and finding no other evidence about 
it, it's hard to judge if it's a valid alternative for the requested use-cases 
or not.

Would you be able to make a 

Re: [whatwg] Script preloading

2013-07-12 Thread Alex Russell
On Fri, Jul 12, 2013 at 4:31 PM, Kyle Simpson get...@gmail.com wrote:

  Ok, and I'm saying they shouldn't be asking LABjs to handle it, they
 should be asking the devtools teams at browser vendors to give them ways to
 deal with it. You're not going to be able to pause execution for code,
 implement future breakpoints, or debug root causes for this sort of thing
 well from script. You can do SOMETHING, but not with the fidelity that
 devtools can.

 I'm not sure why you keep focusing on this being a devtools centric
 question, because I think you're missing the point.

 The developers that are asking for these features from LABjs are NOT
 asking for the capability to debug what's going on with failed loads while
 testing their app in their development environment. IF what they're trying
 to do is diagnose and fix such failed loads while developing their app,
 then certainly that would squarely be a devtools type of task.

 LABjs also has a debug-build available, and it has certain extra tracing
 going on inside it when used, that aids developers in understanding, from
 its perspective, what is going on as things proceed through loading. That
 debug mode, in addition to whatever great devtools that exist or will
 exist, are all fantastic ways for developers to work on and fix problems.

 ***
 But all that is ENTIRELY ORTHGONAL to what the developers are actually
 presently asking from LABjs.
 ***

 They are asking, repeatedly, for the ability to have logic deployed in
 their *production* builds, which sits in front of end users which have no
 knowledge of or relation to any developer tools in whatever browser they
 use. Certainly, these developers are not interested in whether or not their
 end-users happen to be in a browser that has devtools, because end users
 don't care about devtools, and the developers who do care aren't actually
 using the user's browser anyway.


Ok, I think I understand what you're saying now.


 At this point, whether or not a browser has certain devtools is entirely
 irrelevant to what the developer wants from LABjs.

 What seems to be their mindset and internal narrative is this:

 OK, no matter how good we are at figuring out how to build a bug-free
 app, we rely on third-party external resources that we don't control. We
 cannot guarantee that our request for 'jquery.js' from the Google CDN will
 actually work. It should work. It usually works. But it doesn't always
 work. Sometimes Google goes down. Sometimes the DNS lookup fails. Sometimes
 a proxy server misbehaves. Sh$$ happens. SO! We'll just accept that fact.
 We look at our RUM logs and we see that about 2% of our users experience
 one of these dead page loads. But, hey, I've got an idea, how about we try
 to write code into our production code which detects when something like
 that happens, and tries to gracefully recover, if possible, to maybe reduce
 the 2% down to 1%. Yeah, that's a good idea. How do we do that? Oh, I know!
 We're already using a script loader. Let's have that script loader tell us
 when `script.onerror` fires, which tells us that a script load failed
 (right!?!?), and we'll just re-request it from a fallback location on our
 own CDN. Sounds like a plan. Can you file a feature request at LABjs for
 them to expose when `script.onerror` fires? It'd be great if it just could
 automatically re-try or fallback to another URL. Yeah, that sounds cool.
 Sure, will do.

 I understand clearly at this point that you don't agree with their
 mindset. I understand you think their desire is misguided. I admit
 sometimes I am skeptical of the efficacy of such efforts.


It's not scepticism at that level that I'm expressing. Accepting everything
you just typed out (AT EYE-WATERING-LENGTH), changes to Ian's proposal are
still a poor place to attack the issue. The Navigation Controller can give
you everything you want here and more. It's the right hammer for this
particular nail, not dependency attributes.


 But respectfully speaking, your opinion is not the only one that matters
 here.

 Who are we to tell some in-good-faith developer that they are objectively
 WRONG to hope their script loader could not only LOAD scripts but RELOAD or
 ALTLOAD scripts. Think about the conceptual and semantic there. It's a
 pretty sensible expectation for most non-browser-author devs.



  We'll be able to do this from the Navigation Controller:
 https://github.com/slightlyoff/NavigationController/blob/master/explainer.md

 Never heard of it before. Thanks for the link.

 But I don't see how the idea that this may (likely) happen (someday)


We're working on implementing it in Chrome. So yes, both likely and soon.


 automatically moots the discussion at hand. For you to fairly exercise
 some sort of veto vote over what we discuss, which it seems like you're
 trying to do, you've gotta come to the table with some real tangible thing
 that's standardized (or clearly headed that way) and ready to evaluate for
 fitness to the 

Re: [whatwg] Script preloading

2013-07-12 Thread Kyle Simpson
 (AT EYE-WATERING-LENGTH)

I'm sorry I'm too verbose on the list for everyone's taste. Every time I'm 
brief and make assumptions, I get accusations like Jake's repeated ones that 
I'm just asserting without reason.

FWIW, my exhaustion of this process is not about my eyes, but my fingers sure 
take a beating. :)



 Ok, I think I understand what you're saying now.

Happy we're on the same page there, then. :)



 It's not scepticism at that level that I'm expressing. Accepting everything 
 you just typed out (AT EYE-WATERING-LENGTH), changes to Ian's proposal are 
 still a poor place to attack the issue. The Navigation Controller can give 
 you everything you want here and more. It's the right hammer for this 
 particular nail, not dependency attributes.

I'm not arguing for dependency attributes, nor am I arguing that they should or 
should not do this or that. Jake and Ian are. I'm only trying to give them due 
consideration, through my prior posted code snippets (and others I'm working 
on) to examine what they do and do not afford as it relates to the use-cases I 
believe are important to consider.

But I've stated that I actually don't like the dependency attribute, for many 
reasons previously stated, and further reasons I hope to demonstrate through 
the code comparisons Jake suggested. That is an ongoing effort to examine and 
explore the pros-and-cons, and is done in good faith.

Again: my question (which remains unanswered),  the reason I stated the 
error/retry/fallback use case in detail, is whether or not the dependency 
attributes proposal, as put forth by Jake (and Ian) will or will not, factually 
speaking, have any sensitivity to the error conditions (network load error, 
compile error, run-time error) or not, or somewhere in between?

If `dependencies` IS sensitive, in any way, then it clearly overlaps Navigation 
Controller, right? That may or may not be a good thing. If OTOH it has no 
sensitivity whatsoever, and it will trigger a subsequent waiting resource 
regardless of ANY particular network condition or result, that is vital 
information to know, as well.

Either way, shouldn't we afford enough discussion here to discuss how little or 
how much, or if at all, that sensitivity would be? I certainly can't adequately 
judge the proposal in the absence of that information.

Isn't it fair enough for me to inquire as to the actual nature of their 
proposal, given that they've asserted in no uncertain terms that it is fully 
sufficient for all my use-cases? Aren't I entitled to examine that with the 
assistance and participation of this list?

None of that means I necessarily think that Navigation Controller is or is not 
ALSO suitable. I have no opinion on that yet. I stated the reasons why I have 
no opinion on it yet.

Presenting an alternate proposal for one or more use-cases, as you have done, 
is fine. But that doesn't mean that it answers the questions I have about the 
other proposal, by Jake and Ian. Those pre-existing questions are my concern, 
presently.



 We're working on implementing it in Chrome. So yes, both likely and soon.

I look forward to seeing more great documentation on it as we've all come to 
appreciate from the Chrome and Developer relations teams.



 It's unfair of you to expand the scope of a proposed feature to include your 
 pet issue when, logically, it can be separated. See what we both just did 
 there?

Expand the scope? I am not expanding the scope beyond that which I've pushed 
for over and over again for 3+ years, this thread just being the latest 
incarnation. That others (like you) may come to this list with a pre-conceived 
notion of what is and is not in scope doesn't mean that me stating (in 
response to repeated appeals from Jake and others) at length the use-cases *I* 
care about is actually expanding that scope.

Moreover, I am the originator, or at least one of them, of the proposed 
feature, so I hardly think it's fair for you assert that I'm changing the 
game. In reality, I'm clarifying the proposed feature as it relates to my 
viewpoint, as an interested party acting in good faith. I'm recounting the 
substantial prior art in the discussions and discovery and experimentation.

No, I'm not expanding the scope. You (and others) appear to want to be 
narrowing the scope that well pre-dates this thread.

My scope (as it always has been) put simply: I want (for all the reasons here 
and before) to have a silver bullet in script loading, which lets me load any 
number of scripts in parallel, and to the extent that is reasonable, be fully 
in control of what order they run in, if at all, responding to conditions AS 
THE SCRIPTS EXECUTE, not merely as they might have existed at the time of 
initial request. I want such a facility because I want to continue to have 
LABjs be a best-in-class fully-capable script loader that sets the standard for 
best-practice on-demand script loading.



 Better to ask how best to accomplish our goals, not 

Re: [whatwg] Script preloading

2013-07-12 Thread Alex Russell
On Fri, Jul 12, 2013 at 7:56 PM, Kyle Simpson get...@gmail.com wrote:

[ snip ]


 Again: my question (which remains unanswered),  the reason I stated the
 error/retry/fallback use case in detail, is whether or not the dependency
 attributes proposal, as put forth by Jake (and Ian) will or will not,
 factually speaking, have any sensitivity to the error conditions (network
 load error, compile error, run-time error) or not, or somewhere in between?


As per the existing outline, I don't see how it could have any
sensitivity.


 If `dependencies` IS sensitive, in any way, then it clearly overlaps
 Navigation Controller, right? That may or may not be a good thing. If OTOH
 it has no sensitivity whatsoever, and it will trigger a subsequent waiting
 resource regardless of ANY particular network condition or result, that is
 vital information to know, as well.

 Either way, shouldn't we afford enough discussion here to discuss how
 little or how much, or if at all, that sensitivity would be? I certainly
 can't adequately judge the proposal in the absence of that information.

 Isn't it fair enough for me to inquire as to the actual nature of their
 proposal, given that they've asserted in no uncertain terms that it is
 fully sufficient for all my use-cases? Aren't I entitled to examine that
 with the assistance and participation of this list?

 None of that means I necessarily think that Navigation Controller is or is
 not ALSO suitable. I have no opinion on that yet. I stated the reasons why
 I have no opinion on it yet.

 Presenting an alternate proposal for one or more use-cases, as you have
 done, is fine. But that doesn't mean that it answers the questions I have
 about the other proposal, by Jake and Ian. Those pre-existing questions are
 my concern, presently.



  We're working on implementing it in Chrome. So yes, both likely and soon.

 I look forward to seeing more great documentation on it as we've all come
 to appreciate from the Chrome and Developer relations teams.


I owe this list (and others) mail about it. Hoping to have that ready soon.


  It's unfair of you to expand the scope of a proposed feature to include
 your pet issue when, logically, it can be separated. See what we both just
 did there?

 Expand the scope? I am not expanding the scope beyond that which I've
 pushed for over and over again for 3+ years, this thread just being the
 latest incarnation. That others (like you) may come to this list with a
 pre-conceived notion of what is and is not in scope doesn't mean that me
 stating (in response to repeated appeals from Jake and others) at length
 the use-cases *I* care about is actually expanding that scope.


I think you missed the second sentence...


 Moreover, I am the originator, or at least one of them, of the proposed
 feature, so I hardly think it's fair for you assert that I'm changing the
 game. In reality, I'm clarifying the proposed feature as it relates to my
 viewpoint, as an interested party acting in good faith. I'm recounting the
 substantial prior art in the discussions and discovery and
 experimentation.

 No, I'm not expanding the scope. You (and others) appear to want to be
 narrowing the scope that well pre-dates this thread.

 My scope (as it always has been) put simply: I want (for all the reasons
 here and before) to have a silver bullet in script loading, which lets me
 load any number of scripts in parallel, and to the extent that is
 reasonable, be fully in control of what order they run in, if at all,
 responding to conditions AS THE SCRIPTS EXECUTE, not merely as they might
 have existed at the time of initial request. I want such a facility because
 I want to continue to have LABjs be a best-in-class fully-capable script
 loader that sets the standard for best-practice on-demand script loading.



  Better to ask how best to accomplish our goals, not fight over where to
 do that. And that's the spirit I offered the NC in (and pour my work into
 it over). Happy to discuss NC over at the github repo, FWIW.

 Fair enough. That spirit is certainly appreciated.

 At the request of this list, I presented the use-cases as they stand, and
 as they always have. Any solution(s) which reasonably meet them would be a
 good candidate. We're seeking solutions, but we're doing so by exploring
 the fitness of various proposals.

 Over the years, I've championed no fewer than 3 different proposals for
 how I see a single coherent solution that solves all the use cases. That
 alone ought to demonstrate sufficient good-faith that I'm looking for
 solutions, not impetuously defending my pet.

 Moreover, especially with this most recent proposal (script preload), I
 believe it not only sufficient to (trivially) handle *all* the use-cases
 I've presented, but also it is of the nature that it basically would answer
 nearly any other use-case you could imagine in script loading. Certainly my
 list is long but not fully exhaustive of every niche need/desire.

 In light of 

Re: [whatwg] Script preloading

2013-07-12 Thread Kyle Simpson
(being as brief as I possibly can...)


 As per the existing outline, I don't see how it could have any sensitivity.

So, just to clarify, `script dependencies=…` waiting on some other script 
tag is ONLY waiting on that script tag loading to have some sort of positive 
network result, whether that be a 2xx, 3xx, 4xx, or 5xx, and it cares not 
whether the script in question actually loaded, nor whether it fired its 
`onerror` event? Do I have that correct?



 I think you missed the second sentence…

Did I miss some rhetorical levity? Sorry. :)



 That's only your ignorance speaking. There are examples in the repo which you 
 can use to extrapolate examples, or if you a code snippet showing the problem,

I did show a code snippet with the problem already.

Specifically: 
https://gist.github.com/getify/5976429#file-ex2-jaffathecake-js-L54-L68

As I said, I only glanced at your long writeup on Navigation Controller. 
Ignorance is a tiny bit of a pejorative term for my lack of knowledge of some 
non-trivial you just dropped onto the list right in the middle of lots of other 
discussion. But I'll take it in a pleasant light and agree, indeed, that I'm 
ignorant so far of how Navigation Controller can help.

Had it been clear and obvious to me in my initial glances at your document 
immediately how to address the code problem above, I certainly wouldn't have 
exposed such ignorance.

In any case…

 either Jake or I can show how NC would address it.

I would certainly appreciate input on that part of the code I highlighted. As I 
said…

 I look forward to you helping remedy that. :)



--Kyle






Re: [whatwg] Script preloading

2013-07-11 Thread Jake Archibald
On Wednesday, 10 July 2013, Kyle Simpson wrote:

 You know, I keep relying on the fact that the body of work on this topic for 
 almost 3 years … I've spent more time over the last 4+ years obsessing on 
 script loading than any other developer … I am saying the same things I've 
 been saying for 3 years.

This is the open web, length of service does not excuse anyone from
reasoning and evidence.


 But sure, I'll say them, AGAIN, because now someone wants to hear them again.

If you feel you're repeating content from elsewhere, you could have
linked to it (hurrah for the web)! If you hadn't compiled your
use-cases  requirements in one place before, then excellent, you have
now. You can link to this in future.


 I doubt anyone is going to read this crazy long message and actually read all 
 these, but I'll put them here nonetheless.

I am reading this, and I will show how Hixie's #1 solution (plus the
minor additions I suggested) meet your use-cases. For others reading
I'll also detail the use-case in a complete but succinct way.


 1. Premise: I'm the author of a popular and wide-spread used script loader. 
 It's a general utility that's used in tens of thousands of different sites, 
 under a myriad of conditions and in different ways, and in a huge swath of 
 different browsers and devices. I need the ability inside this general 
 utility to do consistent, 100% reliable, predictable script loading for 
 sites, without making ANY assumptions about the site/markup/environment 
 itself. I need to be as unintrusive as possible. It needs to be totally 
 agnostic to where it's used.

Use-case: Script loaders such as LabJS should continue to work at
least as well as they do now.

As you've stated previously, LabJS is complete in that it continues to
work without much development effort. LabJS could either improve by
using the new feature, or not, and continue as is.


 2. Premise: I need a solution for script (pre)loading that works not JUST in 
 markup at page-load time, but in on-demand scenarios long after page-load, 
 where markup is irrelevant. Markup-only solutions that ignore on-demand 
 loading are insufficient, because I have cases where I load stuff on-demand. 
 Lots of cases. Bookmarklets, third-party widgets, on-demand loading of heavy 
 resources that I only want to pay the download penalty for if the user 
 actually goes to a part of the page that needs it (like a tab set, for 
 instance). In fact, most of the code I write ends up in the on-demand world. 
 That's why I care so much about it.

Use-case: I want to preload scripts that execute straight away, such
as social media scripts, and defer their execution. The need for the
script may be determined by script (eg feature detection), so you need
to be able to trigger preload via script. Executing the script should
be optional (user may not interact with the button).

(this is actually many of the use-cases in this email rolled into one,
to save on reading and repetition)

Anyway, here's how you'd preload two scripts and have them execute in
order some time later (but not be held up by other scripts like
async=false). If the script have more flexibility in terms of
execution order, you can specify that and get better performance.

link rel=subresource href=path/to/script.js class=preload
link rel=subresource href=path/to/another-script.js class=preload
script
  // scripts are preloading at this point
  function loadScripts(done) {
var toLoad = document.querySelectorAll('.preload');
var script;
for (var i = 0, len = toLoad.length; i  len; i++) {
  script = document.createElement('script');
  // depend on the previous script
  if (i) script.dependencies = 'script[src=' + toLoad[i-1].href + ']';
  script.src = toLoad[i].href;
  document.head.appendChild(script);
}
script.onload = done;
  }

  loadScripts(function() {
// scripts are ready!
  });
/script

The without-markup solution is the same as above, but the
link[rel=subresource] elements are created conditionally with JS.

link[rel=subresource] is the right solution for preloading, it's what
it's for and it works on more than just script. If there are issues
with this  cache headers, there shouldn't be, let's fix that.

 3. Premise: this is NOT just about deferring parsing. Some people have argued 
 that parsing is the expensive part. Maybe it is (on mobile), maybe not. 
 Frankly, I don't care. What I care about is deferring EXECUTION, not parsing 
 (parsing can happen after-preload or before-execution, or anywhere in 
 between, matters not to me). Why? Because there's still lots of legacy 
 content on the web that has side-effects when it runs. I need a way to 
 prevent those side effects through my script loading, NOT just hoping someday 
 they rewrite their code so that it has no side effects upon execution.

Use-case: this is just the previous use-case with more words.

See above. Although most libraries etc defer major execution to
function calls 

Re: [whatwg] Script preloading

2013-07-11 Thread Jake Archibald
On 10 July 2013 17:37, Jake Archibald jaffathec...@gmail.com wrote:
 On 10 July 2013 16:39, Kyle Simpson get...@gmail.com wrote:
 I personally don't care about scripts being discoverable by pre-parsers. I
 have done testing and am not convinced that something appearing earlier (in
 markup) leads to better performance than allowing my script loading logic to
 load things when I want, and just relying on the browser to do that as
 quickly as possible.


 Pre-parsers can kick in before a page is actually opened, but script cannot
 be executed. Let me dig up some numbers on the benefits of this  report
 back.

Here it is: https://plus.sandbox.google.com/+IlyaGrigorik/posts/8AwRUE7wqAE
~20% improvement.


Re: [whatwg] Script preloading

2013-07-11 Thread Alex Russell
Here's the Plus URL without the googler cruft:

https://plus.google.com/u/1/+IlyaGrigorik/posts/8AwRUE7wqAE


On Thu, Jul 11, 2013 at 3:47 PM, Jake Archibald jaffathec...@gmail.comwrote:

 On 10 July 2013 17:37, Jake Archibald jaffathec...@gmail.com wrote:
  On 10 July 2013 16:39, Kyle Simpson get...@gmail.com wrote:
  I personally don't care about scripts being discoverable by
 pre-parsers. I
  have done testing and am not convinced that something appearing earlier
 (in
  markup) leads to better performance than allowing my script loading
 logic to
  load things when I want, and just relying on the browser to do that as
  quickly as possible.
 
 
  Pre-parsers can kick in before a page is actually opened, but script
 cannot
  be executed. Let me dig up some numbers on the benefits of this  report
  back.

 Here it is:
 https://plus.sandbox.google.com/+IlyaGrigorik/posts/8AwRUE7wqAE
 ~20% improvement.



Re: [whatwg] Script preloading

2013-07-11 Thread Alex Russell
On Thu, Jul 11, 2013 at 9:41 PM, Kyle Simpson get...@gmail.com wrote:

 I'm still going to respond, in detail, with code comparisons, to Jake's
 suggestions that the other proposals besides mine handle all my stated
 use-cases.

 However, before I do that, just to document for posterity, I just recalled
 another use-case which is a feature very frequently requested of LABjs, but
 is impossible with the current web platform. It's so common, I'm not sure
 why I forgot it in the other list, except perhaps sheer exhaustion.



 12: Use-case: you have a string of scripts (A.js, B.js, and C.js)
 loading which constitute a dependency chain. A must run before B, which
 must run before C.

 However, if you detect an error in loading, you stop the rest of the
 executions (and preferably loading too!), since clearly dependencies will
 fail for further scripts, and the errors will just unnecessarily clutter
 the developer console log making it harder to debug.


How is this any different from the case today when script elements are
fetched and run in the situation where one 404's?

And why is the fix not a stop on first script error devtools option
rather than a change to the intrinsics for loading? This is the usual
recourse for most debuggers. Or are you saying we should be able to detect
(via HTTP status code? some other mechanism?) that a script load as
failed before we even attempt to run the code which might depend on it?

I'm unsure how any of this is apropos to the debate at hand. Changes to
this proposal seem entirely the wrong place to be dealing with this sort of
failure/recovery issue.


 One reason developers want this ability to pause/abort part of a chain of
 dependencies is the idea of graceful recovery, where they could re-try
 the failed download again a few times, or perhaps try fallback URLs for a
 script, etc.

 In any case, the desire is to stop C from running if B fails to load, for
 whatever reason.

 In fact, some developers have even requested to be able to stop the chain
 and prevent further executions if the script loads, but there's some
 compile-time syntax error or run-time error that happens during the
 execution. For them, it's not enough for B to simply finish loading
 successfully, but that it must fully execute without error.

 Generally speaking, separate JS files are treated as separate programs and
 are NOT prevented from executing if there's an error running a previous
 file. These developer requests are that they'd like script loaders to be
 able to give them that stop the presses! sort of error handling which
 they currently do not have.

 From my observation of Jake's proposed code, the former part of this
 use-case seems possible, assuming `dependencies` would fail to match on a
 script which resulted in a load error (4xx, 5xx). There would be the extra
 complication that the script loader might switch to an alternate fallback
 URL for a script, in which case it'd have to go find any script elements
 waiting on the previous (failed) URL and update their `dependencies` list
 to the new URL.

 However, it's less clear to me if `dependencies` would fail a match on a
 script that loaded successfully and started trying to run, but had some
 uncaught error happen during compile or execute? If so, fine.

 Would that also mean that if the script loader were to retry (either with
 same or alternate URL) B, and that were to succeed finally, then C would
 then recognize that eventual success (in spite of previous failures) and
 run as expected? If so, fine.

 If however `dependencies` can't be made sensitive to unerrored-execution,
 and there's no other event that a script loader can intercept **between** B
 and C and have a chance to stop C from running (yet), then I think this
 would be a use-case not fully served by what I've seen so far.

 Also, there's the question of what it would mean/tak to stop C from
 running (yet). Perhaps the suggestion is to remove C's script element
 from the DOM for the time being? Would that actually be sufficient to
 prevent it from executing (even if it had already finished loading and was
 just paused waiting)?

 Or perhaps the suggestion would be to temporarily change C's
 `dependencies` list to have some selector in it that's made up and not
 possibly fulfilled, like a made up/impossible script URL, so that C remains
 paused, until a later time when the script loader can come back and set the
 dependencies list back to something sane so that C can resume?





 --Kyle













Re: [whatwg] Script preloading

2013-07-11 Thread Kyle Simpson
 How is this any different from the case today when script elements are 
 fetched and run in the situation where one 404's?

Right now, without any script loader, AFAICT, if A loads fine, B 404's or 
500's, and C loads fine, both A and C will run, and usually C will have lots of 
cascading errors because it assumes B ran when it clearly didn't.

What I'm saying is that quite a few developers have repeatedly asked for LABjs 
to provide some relief to that, because they would like to be able to have 
code-driven logic that tries to gracefully handle such an error. As I said, 
some developers have expressed the desire to have a script loader be able to 
re-try a failed script load a few times. Others have expressed the desire to 
have alternate fallback URL(s) if a script fails to load at its primary 
location.

The point is, normal script tags don't let devs do that AT ALL, and when they 
want to do such things, they hope that a script loader could give them that 
capability. Since LABjs currently relies on script elements in pretty much 
all cases, LABjs can't give them what they want.

As far as I'm concerned, this is absolutely a *candidate* for a perfect 
silver-bullet next-generation script loading mechanism that handles all the 
complex use-cases under discussion thus far under discussion.



 And why is the fix not a stop on first script error devtools option rather 
 than a change to the intrinsics for loading? This is the usual recourse for 
 most debuggers.

As stated, this isn't as much about developers doing things in dev-mode, it's 
about them wanting to have more robust loading logic in their production 
installations that is capable of doing things like script-load-retries or 
script-load-fallback-URLs.

Certainly developers asking LABjs for this don't care nearly as much whether 
other developers can effectively deal with the issue using their devtoosl as 
they care that their production website in front of end-users has the ability 
to respond more robustly, if they care that much in the first place.



 Or are you saying we should be able to detect (via HTTP status code? some 
 other mechanism?) that a script load as failed before we even attempt to 
 run the code which might depend on it?

I was suggesting if we're inventing a new mechanism called `depends` as Jake 
has suggested, it would be nice if that new mechanism was made sensitive to 
things like did the script load successfully (non 4xx/5xx), and even better 
if it could also be sensitive to things like the script load successfully, but 
was there an uncaught error thrown during its main execution?

The more sensitive the mechanism is, the more capable it would be to handling 
the use-cases these developers care about.



 I'm unsure how any of this is apropos to the debate at hand. Changes to this 
 proposal seem entirely the wrong place to be dealing with this sort of 
 failure/recovery issue.

Why so hostile? Isn't it quite apropos/germane to discuss HERE what real-world 
developers want to do (and cannot do currently!) in their code as it relates to 
script loading?

I exhaustively listed out 11 other use-cases of things I care about, as a 
script loader author/maintainer. Are none of those use-cases apropos? Then I 
noted an additional 12th use-case here that I may not personally care as much 
about, but dozens of times developers have filed issues against LABjs 
begging/insisting for.

It appears that some people care enough about production loading robustness 
that they go to extraordinary efforts in their code to detect and respond to 
such conditions. I felt like those many requests to LABjs (and I'm sure other 
script loaders get similar requests) was evidence enough that there's a valid 
use-case to consider and I was just bringing it up for such consideration.



--Kyle




Re: [whatwg] Script preloading

2013-07-11 Thread Kyle Simpson
 I am interested to see how the above use-cases would be met in your
 counter proposal(s) to see if it would be simpler/faster. If LabJS is
 a requirement, it must be factored in as a unit of complexity and
 load-step.
 
 Please do this rather than declare anything to be insufficient without
 reasoning.

It's gonna take a lot of time to write proof-of-concept code for all the 
different nuances and use-cases I've brought up. I'm presenting 2 here. There's 
more to come.

Unfortunately, Jake made a number of simplifying assumptions, or simply missed 
various nuances, in his attempt to combine/reduce/restate my use-case list. I'm 
not ascribing any ill-will to that, but just pointing out that it's not nearly 
as easy as his list might suggest.

I've spent some time trying to put together a first set of code comparisons 
between the `script preload` proposal I've put forth and the `link 
rel=subresource` + `script dependencies=..` proposal Jake is advocating. 
This is by no means an exhaustive comparison or even nearly stating the many 
issues I forsee, but it starts the discussion with actual code instead of 
theoretical concepts.



https://gist.github.com/getify/5976429


There's lots of code comments in there to explain intended semantics, 
outstanding questions/issues, etc.



Some observations/clarifications:

* ex1-getify.js is my attempt at creating a simple `loadScripts()` script 
loader that loads scripts in parallel, but executes them strictly in request 
order, serially.

  -- ONE KEY NOTE: my implementation accomplishes my use case #11 quite 
easily, in that it doesn't start executing any of the scripts in a group until 
ALL the scripts are finished preloading, thus minimizing any gaps/delays 
between them running. I'm able to do this easily because every script fires a 
preload event, so it's trivial to know when all such events have fired as my 
clue on when to start execution.


* ex1-jaffathecake.js is my attempt at doing something as close as possible 
using Jake's proposed way. I've asked for his feedback on this code, so until 
he has a chance to feedback, take it with a grain of salt.

In any case, the code is certainly simpler, but it's missing a KEY COMPONENT: 
it's NOT able to assure what my script loader code does. That is, a.js might 
run long before b.js runs, whereas in my implementation, there should be 
almost no gaps, because a.js doesn't run until b.js is loaded and ready to 
go.

Jake suggested a hack to address this use-case which is based on the idea of 
hiding the whole page while scripts load with gaps in between. This hack is not 
only terribly ugly, but it also misses a big point of my motivation for that 
use-case.

The point is NOT can we hide stuff visually, it's can we make sure stuff 
doesn't run until EVERYTHING is ready to run.

Moreover, as I note in the code comments, it is impossible/impractical for a 
generalized script loader to be able to determine all or parts of a page that 
it should hide, and under what conditions. The script loader is agnostic of 
what it's loading, and it certainly is supposed to be as unobtrusive to the 
hosting page as possible, so it's out of the question to consider that a script 
loader would go and do nuclear-level things like hiding the document element.

The key thing that's missing in Jake's proposal that's necessary to address 
this use-case is that there's no way to be notified that all the scripts have 
finished pre-loading. Instead, his approach obfuscates when things finish 
loading by simply letting the script element internally listen for loads of 
its dependencies.

This is what I mean when I keep saying chicken-and-the-egg, because I want to 
know everything's finished preloading BEFORE I start the execution cursor, but 
in Jake's world, I can't know stuff is finished loading until after I observe 
that it's running.


* ex2-getify.js is a more complex script loader, that takes into account the 
ability to have sub-groups of scripts, where within the sub-group, ASAP 
execution order is desired, and serial-request-order execution order is desired 
across the various sub-groups.

Simply stated: All of C, D, E, and F scripts load in parallel. When it comes to 
execution, C.js runs, then a sub-group of D.js and E.js will run, where 
within the sub-group, either D or E runs first, ASAP (they don't block each 
other), and then when both have run, finally, F.js executes.

This scenario is quite common: I load jquery.js, then I load 4 jquery plugins 
(which are independent), then I load my page's app.js code runs. jquery.js is 
the firs to execute, then the 4 plugins run in ASAP order, then when they're 
all done, finally my app.js code executes.

Also, this more complex script loader listens for `script.onerror` events, and 
if it detects one, it aborts any of the rest of the execution.

Any such error handling is trivial in my loader, because I am always fully in 
control over which script is loading at any given time.


* 

Re: [whatwg] Script preloading

2013-07-11 Thread Bruno Racineux
On browser preloading:

There seems to an inherent conflict between 'indiscriminate' Pre-parsers/
PreloadScanner and responsive design for mobile. Responsive designs
mostly implies that everything needed for a full screen desktop is
provided in markup to all devices.



Isn't the Pre-parsers/PreloadScanner's inability to take into account the
display[none:yes] factor be a potential significant blow to 'mobile'
performance.

Use case: What if I have a set of images in an element set as
display:none; only designated to be show on desktop or tablet screens and
not on mobile phone?

What if I have an inline script in that node?


Isn't the PreloadScanner loading a lot more than I need, a problem here?

In addition to the need to preload, with responsive design taken into
consideration, and for lack of not being able to remove part of the body
before the browser parses the document. I see an increasing potential need
for the ability to indicate to the browser not to load selective assets
before DOMReady and suppress such preload.

Bruno


On 7/11/13 8:23 AM, Alex Russell slightly...@google.com wrote:

Here's the Plus URL without the googler cruft:

https://plus.google.com/u/1/+IlyaGrigorik/posts/8AwRUE7wqAE


On Thu, Jul 11, 2013 at 3:47 PM, Jake Archibald
jaffathec...@gmail.comwrote:

 On 10 July 2013 17:37, Jake Archibald jaffathec...@gmail.com wrote:
  On 10 July 2013 16:39, Kyle Simpson get...@gmail.com wrote:
  I personally don't care about scripts being discoverable by
 pre-parsers. I
  have done testing and am not convinced that something appearing
earlier
 (in
  markup) leads to better performance than allowing my script loading
 logic to
  load things when I want, and just relying on the browser to do that
as
  quickly as possible.
 
 
  Pre-parsers can kick in before a page is actually opened, but script
 cannot
  be executed. Let me dig up some numbers on the benefits of this 
report
  back.

 Here it is:
 https://plus.sandbox.google.com/+IlyaGrigorik/posts/8AwRUE7wqAE
 ~20% improvement.





Re: [whatwg] Script preloading

2013-07-10 Thread Jake Archibald
On 9 July 2013 20:39, Ian Hickson i...@hixie.ch wrote:

 1. Add a dependencies attribute to script that can point to other
scripts to indicate that execution of this script should be delayed
until all other scripts that are (a) earlier in the tree order and (b)
identified by this attribute have executed.

  script id=jquery src=jquery.js async/script
  script id=shims src=shims.js async/script
  script dependencies=shims jquery src=myscript.js async/script

This would download jquery.js, shims.js, and myscript.js ASAP, without
blocking anything else, and would then run jquery.js and shims.js ASAP,
in any order, and then once both have executed, it would execute
myscript.js.


This works for me can we have it now please?

The dependencies attr should make loading non-blocking, even without the
async attr. This produces a nice fallback:

script dependencies id=jquery src=jquery.js/script
script dependencies id=shims src=shims.js/script
script dependencies=#shims, #jquery src=myscript.js/script

Browsers without dependencies support will load the above in a blocking
way, but at least in a dependable order.

Dependencies should be resolved when the element is inserted into the
document, which avoids circular dependencies.
script dependencies=#shims id=jquery src=jquery.js/script
script dependencies=#jquery id=shims src=shims.js/script
The first script above would have no dependencies and will execute as soon
as it downloads, as there was no element with ID shims when dependencies
were resolved.

Also, as above, it'd be great if dependencies took CSS selectors rather
than IDs, this means:
script dependencies=script id=shims src=shims.js/script
becomes the declarative form of async=false.

The CMS plugins from Kyle's example would use dependencies=script until
they become more script-aware.

The dependencies attribute should also work on scripts without src, eg
script dependencies id=jquery src=jquery.js/script
script dependencies=#jquery
  // jquery is ready
/script


 2. Add an whenneeded boolean content attribute, a markNeeded() method,
and an internal is-needed flag (initially false) to the script
element. When a script is about to execute, if its whenneeded=
attribute is set, but its is-needed flag is not, then delay
execution. Calling markNeeded() on a script that has a whenneeded
boolean but that has not executed yet first causes the markNeeded()
method on all the script's dependencies to be called, and then causes
this script to become ready to execute.

  script id=jquery src=jquery.js async whenneeded/script
  script id=shims src=shims.js async whenneeded/script
  script id=myscript dependencies=shims jquery src=myscript.js
  async whenneeded/script

This would download jquery.js, shims.js, and myscript.js ASAP, and then
wait for further instructions.

  document.getElementById('myscript').markNeeded();

This would then cause the scripts to execute, first jquery.js and
shims.js (in any order), and then myscript.js. If any hadn't finished
downloading yet, it would first wait for that to finish.

(We could make markNeeded() return a promise, too.)


I'm similarly not-convinced on delayed parsing/execution. This is better
solved by moving parsing onto a different thread, then the whole web
benefits rather than just those using this new feature. I'm open to
evidence to the contrary.

I've delayed/avoided parsing to great performance benefit on ancient
devices, but this feature won't be adopted there. In this edge-case, hacks
such as HTML comments are best and supported today.

However, if this feature were adopted, dependencies would be redundant,
as I could do it all myself with markNeeded().

script id=jquery src=jquery.js whenneeded/script
script id=shims src=shims.js whenneeded/script
script id=myscript src=myscript.js whenneeded/script
script
  Promise.every(
document.querySelector('#jquery').markNeeded(),
document.querySelector('#shims').markNeeded()
  ).then(function() {
document.querySelector('#myscript').markNeeded()
  });
/script


 Is there a need for delaying the download of a script as well? (If so, we
 could change whenneeded= to have values, like whenneeded=execute vs
 whenneeded=download or something.)


I don't have a use-case for this that isn't handled by dynamic script
insertion.


 Is there something this doesn't handle which it would need to handle?


The dependencies attribute, along with the CSS selector stuff,
'async'-like behaviour by default  if it's allowed on inline scripts meets
all my use-cases.

For completeness, here are my requirements:

   - Does not block page rendering
   - Provides an adoption path for browsers that don't support the new
   feature (happy for the fallback to be blocking document-order execution)
   - Allows scripts to execute in any order as along as their dependencies
   are met (so async=false is not enough)
   - Is 

Re: [whatwg] Script preloading

2013-07-10 Thread Jake Archibald
On 9 July 2013 21:41, Kyle Simpson get...@gmail.com wrote:

 http://wiki.whatwg.org/wiki/Script_Execution_Control

 My proposal was to standardize what IE4-10 did, which is to start loading
 a script even if it's not in the DOM, but not execute it until it's in the
 DOM. Then, you monitor an event to know if one or more scripts have
 finished this preloading, and then you can decide if and when and in what
 order to add the corresponding script elements to the DOM to allow
 execution to proceed.


The IE4-10 technique is invisible to pre-parsers, if we're chasing
performance here it's not good enough.


 Setting aside IE's non-standard event mechanism, Nicholas' proposal was
 also perfectly sensible, and pretty simple. He suggested the same mechanism
 for execution (adding a script to the DOM), but suggested a `preload`
 attribute on the element to prevent auto-execution, and a `onpreload` event
 to notify you of loading-complete.


Also invisible to preloaders.

You could make preload an attribute which does a non-blocking download
but not execution. This is visible to preloaders and falls back to standard
ordered blocking loading which is fine. Then you'd have a method to
trigger execution of the script later. This is Hixie's whenneeded
proposal.

However, whenneeded is more complex than dependencies. Unless there's a
good use-case for deferred parsing that can't be handled by
link[rel=subresource] and similar, dependencies is the better option.

 1. Add a dependencies attribute to script that can point to other
scripts to indicate that execution of this script should be delayed
until all other scripts that are (a) earlier in the tree order and (b)
identified by this attribute have executed.
 
  script id=jquery src=jquery.js async/script
  script id=shims src=shims.js async/script
  script dependencies=shims jquery src=myscript.js async/script

 …content-management-systems (through plugins) load different items into a
 page independently of other plugins. Those plugins have no knowledge of the
 complete content/markup-structure of the page…


If dependencies took a CSS selector it could be:

script dependencies=.cms-core src=cmd-plugin.js/script

Now the number of scripts with class cms-core can change between versions
of the CMS but the plugin still waits for them all. No ID generation
needed. Does this fix the issue for you?


 Moreover, this ignores some use-cases for script preloading which are
 basically speculative preloading. I may want to load several plugins, but
 not execute any of them, and then only use one of them depending on what
 the user does.


This can be better achieved with things like link[rel=subresource] which
work for more than just scripts. When the script is required, it can be
added to the page with js, using something like LabJS or the dependencies
attribute to control execution order if necessary.


 So, the real need here is NOT just to chain a set of scripts together, but
 to put the author in control of pausing a script between load and execute,
 and then they get to decide when/if they unpause a script.


Given the above, is there a usecase that isn't catered for by
dependencies and existing preloading features?


  2. Add an whenneeded boolean content attribute…

 It doesn't solve the I need an event to know when load is finished. If
 I'm waiting for a bunch of stuff to load before asking any of them to
 execute (in the order I want), I need a way to know that each of them are
 in fact fully loaded.


Sorry to keep being Mr Use-case, but what do you need to do that isn't
catered for? You can call markNeeded() when you want the script executed 
both a promise and the script's load event will tell you when it's done.
Why would you need to know when it's downloaded but not executed?


 Secondly, it seems like a bit more complex version of Nicholas' proposal,
 with just different names. Not sure why the complecting of API with
 (mostly) his same semantics.


To me, it seems like a simplification of Nicholas' proposal, but still more
complicated than dependencies without good reason. Also, it works with
preparsers. Can you provide a comparison that shows another suggestion to
be simpler than both of Hixie's proposals and match/beat it's performance?


Re: [whatwg] Script preloading

2013-07-10 Thread Jake Archibald
On 9 July 2013 22:31, Garrett Smith dhtmlkitc...@gmail.com wrote:

 On 7/9/13, Ian Hickson i...@hixie.ch wrote:script id=jquery
 src=jquery.js async/script
   script id=shims src=shims.js async/script
   script dependencies=shims jquery src=myscript.js
 async/script
 

 Why limit depends to be used by only scripts to refer only to other
 scripts?

 If you put link depends=idref on style then stylesheet evaluation
 could be deferred, too.


I like this idea and want to start a family with it.

This would then cause the scripts to execute, first jquery.js and
 shims.js (in any order), and then myscript.js. If any hadn't finished
 downloading yet, it would first wait for that to finish.
 
 (We could make markNeeded() return a promise, too.)
 
 Or use a callback. Blocking on resource loading is bad.


Promises don't block. New APIs that want callbacks for async
success/failure should use Promises.


Re: [whatwg] Script preloading

2013-07-10 Thread Bruno Racineux

On 7/9/13 7:09 PM, Kyle Simpson get...@gmail.com wrote:

 I have been wrestling pretty hard with script loading issues lately. I'd
 say that having the browser manage script interdependency is probably a
 bad and cumbersome way to solve these issues.

What do you mean by having the browser manage script interdependency?
As far as I am aware, this thread and these feature requests are not
about the browser managing script interdependenciesŠ in fact, quite the
opposite. What we're asking and hoping for is a facility that allows the
app code to manage the dependencies and the loading order, while only
relying on the browser to do the actual loading for us the way it always
has.

Maybe we diverge on semantics. When you say while only relying on the
browser to do the actual loading for us the way it always has. That's not
really what I am seeing.

The suggestion #2. given by Ian is not only doing the loading per say.
The browser has to figure out the dependencies from the dependency
information given in a DOM format. That's essentially what I mean by
delegating the dependency management to the browser.

Anyway, as per your previous email I think we mostly agree that solution
#1 is not very practical (or infeasible per your word) and #2 is awfully
complex.

The only part of that puzzle that's missing is a way to tell the browser
to pause between finishing-loading and starting-executing. Asking for
such a mechanism has really nothing to do with offloading dependency
management to the browser to handle. It's empowering the app code to be
more in control, not less.
 
I think that preloading without executing is really what we should are
after.
But there has to be a simpler way to do this.



 I think one of the reason that people may ask for this Interdependency
 feature,
 is due to the weakness of the platform they use,

Again, I think you may possibly be misunderstanding the goal of what's
being asked for. But I'll agree with you that there's a weakness. The
weakness, IMO, is in the web platform itself, in not giving us more
fine-grained control over script loading. That is why we keep having this
discussion every 6 months or so for the least several years. The
use-cases never go away, and the hacks we use to deal with them never get
any less ugly.

 And 'async', while good for independent scripts such as social media
apis,
 is not really a good tools for dependency management.

Again, possibly a case of misunderstanding or missed context from
previous conversations. When I bring up async, I'm not talking about
script async in markup as you suggest, but actually `script.async =
false` being set on dynamcially created script elements (in code).
async=false (aka ordered async) is a relatively new feature added
to the platform about 2.5 years ago that gives us async parallel loading,
but the browser automatically enforces execution order to be request
order, instead of ASAP order.

async=false is actually a good feature. The problem is not the feature
itself, but that it's only part of what we needed.

I see. I am shamefully new to the notion that async=false is ordered
async. It apparently went quite off specs through vendors first to make
this work, with no much of an official documentation, hence me missing it
I guess... Though it kind of make me cringe that vendors jumped on
implementing such new slightly unintuitive feature, while HTML4 specs like
'defer' were left unreliable. It feel like priorities worked slightly
backwards...

Nevertheless ordered async is very useful as solving part of the problem
indeed.



 My main issue against using external script loaders like LABjs and
others,
 has always been that if the browser must download a script first, before
 starting to download the dependencies. It presents a drawback already,
for
 delayed the scripts by the script loader's latency and download time (at
 least for the first uncached page load) similarly to having scripts at
the
 bottoms.

For LABjs' part, I never suggest to people to load LABjs in a separate
file. I suggest that people use a bootstrap type code file, which would
be a single .js file they load with a single script tag in their
markup, and it contains all the bare-minimum code necessary to bootstrap
the page/app. It would include the code for LABjs, also the $LAB chains
for loading other scripts, even basic event handling or other bootstrap
type logic.

Moreover, the extra ~2k of gzip-bytes that LABjs costs (even if it's a
separate file, but especially if it's included in another bootstrap file)
is almost always made up for in savings by being able to take advantage
of consistent parallel loading of scripts.

If your page only has 3-5k of JS on it, then you shouldn't use a script
loader. But if you're like most sites, and you're loading 100-300k of JS,
then a tiny 2k of JS for loading optimization is not even a drop in the
ocean.

It's not the size that bothers me. It's the inevitable first time delay.
Ideally all scripts needed before 

Re: [whatwg] Script preloading

2013-07-10 Thread Jake Archibald
On 10 July 2013 11:31, Bruno Racineux br...@hexanet.net wrote:

 Anyway, as per your previous email I think we mostly agree that solution
 #1 is not very practical (or infeasible per your word)


Given the suggestions I made to #1 in
http://lists.whatwg.org/htdig.cgi/whatwg-whatwg.org/2013-July/039968.html,
do you still think it's impractical (and why)?


 I think that preloading without executing is really what we should are

after.


*hits usecase button* Why would you want to do that? Are those cases
already (better) solved by link[rel=subresource] and dynamic script
insertion?


Re: [whatwg] Script preloading

2013-07-10 Thread Kyle Simpson
 The IE4-10 technique is invisible to pre-parsers, if we're chasing 
 performance here it's not good enough.
 ...
 Also invisible to preloaders.

I personally don't care about scripts being discoverable by pre-parsers. I have 
done testing and am not convinced that something appearing earlier (in markup) 
leads to better performance than allowing my script loading logic to load 
things when I want, and just relying on the browser to do that as quickly as 
possible.

For instance, I've added like link rel=prefetch annotations for my scripts 
into the head of my document, and then done my normal script-based script 
loading as usual, and benchmarked if them being in the markup somehow magically 
sped up the page. I saw no appreciable increase in average page load speed in 
my testing.

It's quite possible that this is because when I use script loading, generally 
speaking, I'm only loading the scripts I consider to be most critical for 
actual page load (not everything and the kitchen sink), so my script-based 
script loading during page-load usually is pretty darn quick. I defer the 
rest of my code that's not as critical until later (perhaps until when needed, 
strictly), which is something that markup alone doesn't let me do.

I like the fact that I can have my bootstrapper load.js file either at the 
very top (and thus it starts loading them nearly immediately) if the scripts I 
want to load are more important than the images and stylesheets in the markup, 
OR I can put my load.js file at the bottom of the markup and thus give a chance 
for other content to start loading slightly before my scripts start loading.

The fact that browsers are trying to second guess developers and look-ahead to 
find and prioritize certain resources is NOT something I consider a positive 
benefit that I'm eager to assist. I still come from a world where a developer 
ought to get to decide what's higher priority.

There's certainly a strong pre-disposition among a lot of developers to falling 
in love with declarative markup-only solutions. I share no such obsession, when 
it comes to script loading. I think script loading is far more complex than 
markup is ever going to be equipped to handle.

To be clear, I will not be satisfied with a markup-only approach. No matter how 
complex it is, it does not handle all the use-cases I care about. I feel like a 
broken record on these threads, because I keep talking about why markup-only is 
insufficient, and people keep trying to convince me they can make markup more 
and more complex and certainly they'll eventually convince me that markup-only 
is superior. The more complex you make the markup-only proposals, the more I'm 
convinced (and self-validated) that markup is the wrong tool for the complex 
use-cases I care about.

---

All that having been said, I am not trying to block a solution that would BOTH 
serve those who have a subset of (simpler) use-cases which are markup-centric, 
and those of us who care about serving more complex use-cases via code. A 
solution that both camps can accept is better than either camp being happy to 
the exclusion of the other.

I would be fine if we went with a variation of Nicholas' proposal. Let me state 
that new proposal here:


**
Summary:

1. `preload` attribute on script tags in markup, `preload` property on script 
elements created by code. In either case, its presence tells the browser not to 
execute the script once it finishes loading.

2. `onpreload` event fired on any script which has `preload` attribute or 
property on it at the time its (pre)loading finishes (and execution is thus 
suppressed). Otherwise, not fired.

3. To execute a script that was preloaded in code, remove the `preload` 
attribute or property from the element, which signals to the browser that it's 
OK to execute it now. If you remove it before loading finishes, the browser 
acts as if it was never marked as preload and continues as normal. If you 
remove it after preloading finishes, the browser is free to execute that script 
ASAP now.

4. If you are doing markup-only loading, you signal to a preloaded script 
that its eligible for execution by putting a matching selector to it into a 
`fulfills` attribute on another script element. If a script finishes loading 
and it's already been signaled by another `fulfills`, it will run right away. 
Otherwise, it'll wait until some script executes that has a matching `fulfills` 
attribute on it.



Details:

The behavior of preload-but-don't-execute is controlled by the markup presence 
of a `preload` attribute on script tags (thus discoverable by pre-parsers), or 
a corresponding `preload` property in the script-based loading scenario. BOTH 
sides of the feature have to be implemented -- markup only is NOT enough for my 
needs.

That attribute/property being present/set would be the only thing that signals 
to the browser load this script, but DON'T auto-execute it until told to do 

Re: [whatwg] Script preloading

2013-07-10 Thread Kyle Simpson
 **
 Summary:
 
 1. `preload` attribute on script tags in markup, `preload` property on 
 script elements created by code. In either case, its presence tells the 
 browser not to execute the script once it finishes loading.
 
 2. `onpreload` event fired on any script which has `preload` attribute or 
 property on it at the time its (pre)loading finishes (and execution is thus 
 suppressed). Otherwise, not fired.
 
 3. To execute a script that was preloaded in code, remove the `preload` 
 attribute or property from the element, which signals to the browser that 
 it's OK to execute it now. If you remove it before loading finishes, the 
 browser acts as if it was never marked as preload and continues as normal. 
 If you remove it after preloading finishes, the browser is free to execute 
 that script ASAP now.
 
 4. If you are doing markup-only loading, you signal to a preloaded script 
 that its eligible for execution by putting a matching selector to it into a 
 `fulfills` attribute on another script element. If a script finishes loading 
 and it's already been signaled by another `fulfills`, it will run right away. 
 Otherwise, it'll wait until some script executes that has a matching 
 `fulfills` attribute on it.

A variation on my proposal which gives a little more symmetry between 
markup-based loading and script-based loading:

Instead of removing the `preload` attribute/property to signal it's OK to 
execute now, I just set another property on it called `fulfilled`. That 
attribute/property, if present at time of preload completion, means it's OK, 
go ahead an execute, or if added after preload, says go ahead and execute it 
now ASAP.

The symmetry is that in markup-only usage, I use `fulfills` on another script 
tag (because with markup only I can't modify another script element) to signal 
that the preloaded script element is now fulfilled. But in script-based 
loading, I can just signal the preloaded script element directly that it's 
fulfilled now by setting a `fulfilled` property on it.

I like that even a lot better than deleting/removing the `preload` 
attribute/property.




--Kyle






Re: [whatwg] Script preloading

2013-07-10 Thread Jake Archibald
On 10 July 2013 16:39, Kyle Simpson get...@gmail.com wrote:

  The IE4-10 technique is invisible to pre-parsers, if we're chasing
 performance here it's not good enough.
  ...
  Also invisible to preloaders.

 I personally don't care about scripts being discoverable by pre-parsers. I
 have done testing and am not convinced that something appearing earlier (in
 markup) leads to better performance than allowing my script loading logic
 to load things when I want, and just relying on the browser to do that as
 quickly as possible.


Pre-parsers can kick in before a page is actually opened, but script cannot
be executed. Let me dig up some numbers on the benefits of this  report
back. But logically, [parse html]-[load script] is always going to be
faster than [parse html]-[parse inline script]-[execute inline
script]-[load script]. And I imagine, more bytes and complex.


 It's quite possible that this is because when I use script loading,
 generally speaking, I'm only loading the scripts I consider to be most
 critical for actual page load (not everything and the kitchen sink), so my
 script-based script loading during page-load usually is pretty darn quick.
 I defer the rest of my code that's not as critical until later (perhaps
 until when needed, strictly), which is something that markup alone doesn't
 let me do.


If it's something likely to be used later you're better off loading it with
the page. Waking up the radio on a mobile connection is slow and uses
battery. Having said that, there's nothing in either of the original
proposals that prevents adding scripts dynamically. It's the more complex
option if you want more complex behaviour.


 The fact that browsers are trying to second guess developers and
 look-ahead to find and prioritize certain resources is NOT something I
 consider a positive benefit that I'm eager to assist. I still come from a
 world where a developer ought to get to decide what's higher priority.


Browsers already do this to proven benefit, but download priority is
outside the scope of this discussion.


 There's certainly a strong pre-disposition among a lot of developers to
 falling in love with declarative markup-only solutions. I share no such
 obsession, when it comes to script loading. I think script loading is far
 more complex than markup is ever going to be equipped to handle.

 To be clear, I will not be satisfied with a markup-only approach. No
 matter how complex it is, it does not handle all the use-cases I care about.


Which of your use-cases have not been met? So far I've seen only I want X,
Y, Z but not what you need X, Y, Z to achieve that isn't covered by other
simpler proposals or existing features.

I would be fine if we went with a variation of Nicholas' proposal. Let me
 state that new proposal here:

 …



2. `onpreload` event fired on any script which has `preload` attribute or
 property on it at the time its (pre)loading finishes (and execution is thus
 suppressed). Otherwise, not fired.


What do you need to do that requires this event?

I don't understand what this proposal has over Hixie's proposal other than
proposed-by-Kyle :)


 It continues to be wrongly asserted that the current `onload` event on
 scripts is sufficient. It is not. It's a chicken-and-the-egg, because
 `onload` is fired strictly when scripts have loaded AND executed. We need
 an event to tell us when it's ONLY loaded but strictly HASN'T executed yet,
 which makes `onload` insufficient.


For the rest of this discussion I need you to understand that saying We
need x is not proof enough that we need x. Please explain why it's needed
and how you would use it to do something that couldn't be done without it.

script id=jquery src=jquery.js whenneeded/script
script id=shims src=shims.js whenneeded/script
script id=myscript src=myscript.js whenneeded/script
script
  Promise.every(
document.querySelector('#jquery').markNeeded(),
document.querySelector('#shims').markNeeded()
  ).then(function() {
document.querySelector('#myscript').markNeeded()
  });
/script

The above doesn't need an extra event. In fact, your proposal doesn't need
an extra event, I could remove the preload attribute and wait for onload,
it doesn't matter if the script has been preloaded or not. Maybe I'm
missing a use-case, but I need you to show what that is.


 It's quite clear and obvious how the `onpreload` event is useful to
 script-based loading.


Don't tell us it's clear and obvious, just make it clear and obvious.
Provide an example that requires it.

Before we look closer at this load-but-don't-execute pattern we need a good
reason. One that isn't already covered by the #1 idea in the first email +
link[rel=subresource] + dynamic script adding.


  Given the above, is there a usecase that isn't catered for by
 dependencies and existing preloading features?

 Yeah, consider this scenario: I want to preload 1.js and 2.js, but I'm
 not sure right now if I'll execute 1.js, or 2.js, or both. The user
 

Re: [whatwg] Script preloading

2013-07-10 Thread Kornel Lesiński

On Wed, 10 Jul 2013 16:39:42 +0100, Kyle Simpson get...@gmail.com wrote:


I personally don't care about scripts being discoverable by pre-parsers.

[...]
For instance, I've added like link rel=prefetch annotations for my  
scripts into the head of my document, and then done my normal  
script-based script loading as usual, and benchmarked if them being in  
the markup somehow magically sped up the page. I saw no appreciable  
increase in average page load speed in my testing.


The result you've seen is expected, as pre-parser and link prefetching are  
different mechanisms.


Prefetching of resources from rel=prefetch is only done after page  
completely finishes loading, so it won't affect loading time of page that  
contains it (it's for future navigation, like step1.html containing  
prefetch for step2.html).


There's rel=subresource that's for immediate prefetching in the way  
you'd expect. You should see some improvement with it in cases where  
script loader makes it impossible for browser to start fetching scripts  
before the script loader is run:

http://www.chromium.org/spdy/link-headers-and-server-hint/link-rel-subresource

HTML pre-parser is basically equivalent of having rel=subresource for  
all script elements.


--
regards, Kornel


Re: [whatwg] Script preloading

2013-07-10 Thread Alex Russell
This is a good proposal and I'm hugely excited to see this getting more
attention! Thanks so much for bringing it up again.

There's one state that's not represented here which is download but do not
run, an inactive flag, if you will. I know this is important is some
situations where the overhead to compile code is potentially large...but
it's an edge-case. markNeeded() might cover it.

Regarding dependencies=...; have you considered a way to set up script
groups instead of ID-based dependencies? E.g.:

  script group=core src=jquery.js async whenneeded/script
  script group=shims src=shims.js async whenneeded/script
  script id=myscript group=core shims src=myscript.js
 async whenneeded/script

With the idea being that each item depends on other items in the specified
group in document order. I'm not sure it's better, but it might enable less
a-priori collaboration across large sets of dependent scripts.

Also, have you talked at all with Yehuda, Dave, and Sam about how this
might interact with ES6 Module Loaders? It might be worth a discussion just
to see if there are any bits of common infrastructure that both designs can
identify/re-use. They'll all bottom out at fetch() someplace, but
understanding how they interact might be helpful. E.g., could I specify a
named module loader for a script? That'd make transpilers infinitely more
useful.

Again, thanks for posting this. I'm incredibly excited about this design
and would support it without changes.



On Tue, Jul 9, 2013 at 8:39 PM, Ian Hickson i...@hixie.ch wrote:


 A topic that regularly comes up is script loading.

 I sent an e-mail responding to related feedback last year, though it
 didn't get any replies to the script loading parts of it:


 http://lists.w3.org/Archives/Public/public-whatwg-archive/2012Dec/0221.html

 It seems that people want something that:

  - Lets them download scripts but not execute them until needed.
  - Lets them have multiple interdependent scripts and have the browser
manage their ordering.
  - Do all this without having to modify existing scripts.

 I must admit to not really understanding these requirements (script
 execution can be made more or less free if they are designed to just
 expose some functions, for example, and it's trivial to set up a script
 dependency mechanism for scripts to run each other in order, and there's
 no reason browsers can't parse scripts off the main thread, etc). But
 since everyone else seems to think these are issues, let's ignore that.

 The proposals I've seen so far for extending the spec's script preloading
 mechanisms fall into two categories:

  - provide some more control over the mechanisms already there, e.g.
firing events at various times, adding attributes to make the script
loading algorithm work differently, or adding methods to trigger
particular parts of the algorithm under author control.

  - provide a layer above the current algorithm that provides strong
semantics, but that doesn't have much impact on the loading algorithm
itself.

 I'm very hesitant to do the first of these, because the algorithm is _so_
 complicated that adding anything else to it is just going to result in
 bugs in browsers. There comes a point where an algorithm just becomes so
 hard to accurately test that it's a lost cause.

 The second seems more feasible, though.

 Would something like this, based on proposals from a variety of people in
 the past, work for your needs?

 1. Add a dependencies attribute to script that can point to other
scripts to indicate that execution of this script should be delayed
until all other scripts that are (a) earlier in the tree order and (b)
identified by this attribute have executed.

  script id=jquery src=jquery.js async/script
  script id=shims src=shims.js async/script
  script dependencies=shims jquery src=myscript.js async/script

This would download jquery.js, shims.js, and myscript.js ASAP, without
blocking anything else, and would then run jquery.js and shims.js ASAP,
in any order, and then once both have executed, it would execute
myscript.js.

 2. Add an whenneeded boolean content attribute, a markNeeded() method,
and an internal is-needed flag (initially false) to the script
element. When a script is about to execute, if its whenneeded=
attribute is set, but its is-needed flag is not, then delay
execution. Calling markNeeded() on a script that has a whenneeded
boolean but that has not executed yet first causes the markNeeded()
method on all the script's dependencies to be called, and then causes
this script to become ready to execute.

  script id=jquery src=jquery.js async whenneeded/script
  script id=shims src=shims.js async whenneeded/script
  script id=myscript dependencies=shims jquery src=myscript.js
  async whenneeded/script

This would download jquery.js, shims.js, and myscript.js ASAP, and then
wait 

Re: [whatwg] Script preloading

2013-07-10 Thread Kyle Simpson
 Which of your use-cases have not been met? So far I've seen only I want X, 
 Y, Z but not what you need X, Y, Z to achieve that isn't covered by other 
 simpler proposals or existing features.

You know, I keep relying on the fact that the body of work on this topic for 
almost 3 years ought NOT have to be re-visited every few months when these 
threads wake from dormancy. I keep hoping that someone who really cares about 
actually addressing all the concerns, and not just some of them, will do the 
due dilligence to look at all the previous stuff before criticizing me for not 
providing enough detail.

I've written nearly a book's worth on this over all the threads and sites and 
blog posts over the years. In fact, I think its fair to say at this point that 
I've spent more time over the last 4+ years obsessing on script loading than 
any other developer, anywhere, ever.

I don't like the implication that I'm apparently just an impetuous little child 
demanding my way with no reasoning.

So, fine. Here it is. I'm going to state explicitly the use-cases I care about. 
This is nothing new. I am saying the same things I've been saying for 3 years. 
But sure, I'll say them, AGAIN, because now someone wants to hear them again. I 
doubt anyone is going to read this crazy long message and actually read all 
these, but I'll put them here nonetheless.

And I'm listing them here because they are not covered fully by any of the 
other proposals besides the 2 or 3 I keep pushing for. You may think they are 
covered, but I think the nuances prove that they aren't. The devil is always in 
the details. Or you may think my use-cases are irrelevant and so you dismiss 
them as unimportant. Guess there's nothing I can do about that.


-

1. Premise: I'm the author of a popular and wide-spread used script loader. 
It's a general utility that's used in tens of thousands of different sites, 
under a myriad of conditions and in different ways, and in a huge swath of 
different browsers and devices. I need the ability inside this general utility 
to do consistent, 100% reliable, predictable script loading for sites, without 
making ANY assumptions about the site/markup/environment itself. I need to be 
as unintrusive as possible. It needs to be totally agnostic to where it's used.


2. Premise: I need a solution for script (pre)loading that works not JUST in 
markup at page-load time, but in on-demand scenarios long after page-load, 
where markup is irrelevant. Markup-only solutions that ignore on-demand loading 
are insufficient, because I have cases where I load stuff on-demand. Lots of 
cases. Bookmarklets, third-party widgets, on-demand loading of heavy resources 
that I only want to pay the download penalty for if the user actually goes to a 
part of the page that needs it (like a tab set, for instance). In fact, most of 
the code I write ends up in the on-demand world. That's why I care so much 
about it.


3. Premise: this is NOT just about deferring parsing. Some people have argued 
that parsing is the expensive part. Maybe it is (on mobile), maybe not. 
Frankly, I don't care. What I care about is deferring EXECUTION, not parsing 
(parsing can happen after-preload or before-execution, or anywhere in between, 
matters not to me). Why? Because there's still lots of legacy content on the 
web that has side-effects when it runs. I need a way to prevent those side 
effects through my script loading, NOT just hoping someday they rewrite their 
code so that it has no side effects upon execution.

NOTE: there ARE people who care about the expense of parsing. Gmail-mobile (at 
one point, anyway) was doing the /* here's my code */ comment-execute trick to 
defer parsing. So me not caring about it doesn't make it not an important 
use-case. Perhaps it IS something to consider. But it doesn't change any of my 
proposals or opinions -- it leaves the door open for the browser to decide when 
parsing is best.


4. Use-case: I am dynamically loading one of those social widgets that, upon 
load, automatically scans a page and renders social buttons. I need to be able 
to preload that script so it's ready to execute, but decide when I want it to 
run against the page. I don't want to wait for true on-demand loading, like 
when my user clicks a button, because of the loading delay that will be visible 
to the user, so I want to pre-load that script and have it waiting, ready at a 
moment's notice to say it's ok to execute, do it now! now! now!.

There is not this script has loaded, so run the other one scenario here. It's 
some run-time environment condition, such as user-interaction, which needs to 
be the trigger. For instance, it might be when I finish using a templating 
engine client-side to render the markup that the social widget will search for 
and attach to. Or it might be like clicking to open a tab, which isn't rendered 
until made visible, and so we can't run the social widget code until that tab 
is rendered and 

Re: [whatwg] Script preloading

2013-07-10 Thread Kyle Simpson
 Pre-parsers can kick in before a page is actually opened, but script cannot 
 be executed. Let me dig up some numbers on the benefits of this  report 
 back. But logically, [parse html]-[load script] is always going to be faster 
 than [parse html]-[parse inline script]-[execute inline script]-[load 
 script]. And I imagine, more bytes and complex.

That they *can* do that is not sufficient proof that in the real-world, it 
actually does speed up page loads. In my testing, the way I do script loading, 
annotating scripts in the markup and then doing my normal script loading did 
not, on average, provide any noticeable speed up.

But anyway, this is a moot discussion, because I already conceded that if we 
want a solution that helps markup-only advocates, that's fine. script preload 
does that. Why are we going to keep arguing that point?

No matter how that plays out, it doesn't change the fact that I need a solution 
which works for on-demand loading long after page-load, where what was or 
wasn't in the markup during that magical not rendered yet state is completely 
irrelevant.

I feel like we're on a merry-go-round the last few years where someone says 
but, look, this is better in markup at page-load and then I say whatever, 
fine, but it doesn't help on-demand and then we go back around to no no, this 
is better for page-load.

I don't consider this an either/or proposition. You have your thing you care 
about, I have my thing I care about. Both should be important.



 If it's something likely to be used later you're better off loading it with 
 the page. Waking up the radio on a mobile connection is slow and uses 
 battery. Having said that, there's nothing in either of the original 
 proposals that prevents adding scripts dynamically. It's the more complex 
 option if you want more complex behaviour.

This is a big over-simplification of the scenarios involved. Sure, in general, 
you want to minimize waking the radio back up, but if there's 10% of script 
code I need to render the page initially, and 90% of my code is needed later 
(or maybe, conditionally, never at all), it's not supportable performance-wise 
to say well, just slow down the initial page render for that 90%.

We have the techniques of post-loading and on-demand loading for a reason, and 
there are cases where you can prove, through testing, that doing dynamic 
loading after page-load is objectively better than slowing down the initial 
page load. Not only *can* you prove it, I have proven it on my own sites. Time 
and again.

I'm sure there are ALSO cases where requesting everything at once is better. 
But there is no proof yet presented that always requesting everything all at 
once is always, unconditionally, the best option. If you have such evidence, 
and can prove that 100% of sites/apps which use on-demand loading are doing it 
wrong, please present that evidence.

Short of that evidence, I live in a world that accepts that sometimes one is 
better, sometimes the other is better. And I want a solution that equally 
empowers both sides of the coin, not just one.


-

I'm going to stop this email here, and reply with another reply regarding your 
request for use-cases detail. That one is going to be QUITE long.




--Kyle

Re: [whatwg] Script preloading

2013-07-10 Thread Yoav Weiss
I'm supportive of this proposal, and I think it'd help declarative script
loading.

I've recently contemplated the slightly related issue of adding the media
attribute to script, for declarative loading of scripts that are only
relevant to some viewports [1]
While it may complicate certain things (e.g. execution when media
conditions change, dependencies), I believe it's worth while to give it
some thought, as it'd enable preloaders to fetch these scripts as soon as
possible, in case they are needed.


Regarding Kyle's list of use-cases, I think it can be summed up to
something like:
Authors often need to load 3rd party scripts into their pages (e.g. ads,
widgets, analytics). These scripts are out of their control, and often do
not allow the hosting page to determine when they are executed.
In many cases, either for performance (they trigger download of their own
resources) or for UX purposes (they display something on the screen),
authors need to control when these scripts are executed.

IMO, the proposed whenneeded attribute can answer that need.
rel=subresource can also answer it (assuming that browsers will optimize on
it: download the resource, detect its type and parse it (as low priority)
if needed, and keep it in memory regardless of its caching headers), but
IMO whenneeded is cleaner.

For the #11 use-case, where you want to delay the execution of some scripts
until an entire group of scripts have finished downloading, but have yet to
run, it could be done with:
script id=A src=A.js dependencies=B C async whenneeded/script
script id=B src=B.js async whenneeded/script
script id=C src=C.js async whenneeded/script

script
var a=document.getElementById(A),
 b=document.getElementById(B),
 c=document.getElementById(C);
a.markNeeded().then(function(){b.markNeeded()}).then({function(){c.markNeeded()});
/script

That would work, as long as a dependency when the script we're dependent on
is defined as whenneeded becomes dependency on its download, rather than
its execution. Does that make sense?

[1]
http://lists.w3.org/Archives/Public/public-whatwg-archive/2013May/0112.html


Re: [whatwg] Script preloading

2013-07-10 Thread Bruno Racineux
On 7/10/13 4:20 AM, Jake Archibald jaffathec...@gmail.com wrote:

On 10 July 2013 11:31, Bruno Racineux br...@hexanet.net wrote:

Anyway, as per your previous email I think we mostly agree that solution
#1 is not very practical (or infeasible per your word)


Given the suggestions I made to #1 in
http://lists.whatwg.org/htdig.cgi/whatwg-whatwg.org/2013-July/039968.html,
do you still think it's impractical (and why)?
I think the very idea of having the concept of 'dependency' attributes and
relying or asking to the browser to handle it through markup is misguided.

This is somehow throwing the entire (or a portion of) dependency
information of your platform, asking the browser to deal with it.
I can already imagine bloated pages with an entire set of script markup,
bigger than that of the page itself. That's not very good for performance.

I think Kyle has given more than enough substantiated arguments in:
http://lists.whatwg.org/htdig.cgi/whatwg-whatwg.org/2013-July/039981.html
not to have me repeat them.





I think that preloading without executing is really what we should are

after.


*hits usecase button* Why would you want to do that? Are those cases
already (better) solved by link[rel=subresource] and dynamic script
insertion?
Again I'll differ to Kyle's extensive list for the use case.
Modular approach, widgets, etc.

As for link [rel=subresource] I am slightly unclear at to its full purpose
really.
Unless I am mistaken, (and if so correct me) it's a priority-prefetch. No
a preload.

While slightly useful. It doesn't really address, the pre-load that
script and have it waiting, ready at a moment's notice to say it's ok to
execute, do it now! now! now!. :)


An alternative perhaps ignorant suggestion:


Wouldn't a link[rel=preload] sending cookies would be simpler tool for
basic script-preloading? In that I could dynamically insert a list of
subresources to have them ready. Leaving the loading part to markup. And
the request part to javascript.

In order to address caching caveats (or possible lack of caching headers)
that Kyle mentioned. rel=preload would guarantee a one time cache as well
a pre-parsing the resource according, to its link 'type' if provided (i.e.
css, js, etc).

Now wether a HXR request from there has a cross-browser hurdle when the
script is already in the cache is something I am not familiar with...

And I am unfortunately very confused on the link[prerender] spec for
scripts.




[whatwg] Script preloading

2013-07-09 Thread Ian Hickson

A topic that regularly comes up is script loading.

I sent an e-mail responding to related feedback last year, though it 
didn't get any replies to the script loading parts of it:

   http://lists.w3.org/Archives/Public/public-whatwg-archive/2012Dec/0221.html

It seems that people want something that:

 - Lets them download scripts but not execute them until needed.
 - Lets them have multiple interdependent scripts and have the browser
   manage their ordering.
 - Do all this without having to modify existing scripts.

I must admit to not really understanding these requirements (script 
execution can be made more or less free if they are designed to just 
expose some functions, for example, and it's trivial to set up a script 
dependency mechanism for scripts to run each other in order, and there's 
no reason browsers can't parse scripts off the main thread, etc). But 
since everyone else seems to think these are issues, let's ignore that.

The proposals I've seen so far for extending the spec's script preloading 
mechanisms fall into two categories:

 - provide some more control over the mechanisms already there, e.g. 
   firing events at various times, adding attributes to make the script 
   loading algorithm work differently, or adding methods to trigger 
   particular parts of the algorithm under author control.

 - provide a layer above the current algorithm that provides strong 
   semantics, but that doesn't have much impact on the loading algorithm 
   itself.

I'm very hesitant to do the first of these, because the algorithm is _so_ 
complicated that adding anything else to it is just going to result in 
bugs in browsers. There comes a point where an algorithm just becomes so 
hard to accurately test that it's a lost cause.

The second seems more feasible, though.

Would something like this, based on proposals from a variety of people in 
the past, work for your needs?

1. Add a dependencies attribute to script that can point to other 
   scripts to indicate that execution of this script should be delayed
   until all other scripts that are (a) earlier in the tree order and (b) 
   identified by this attribute have executed.

 script id=jquery src=jquery.js async/script
 script id=shims src=shims.js async/script
 script dependencies=shims jquery src=myscript.js async/script

   This would download jquery.js, shims.js, and myscript.js ASAP, without 
   blocking anything else, and would then run jquery.js and shims.js ASAP, 
   in any order, and then once both have executed, it would execute 
   myscript.js.

2. Add an whenneeded boolean content attribute, a markNeeded() method,
   and an internal is-needed flag (initially false) to the script 
   element. When a script is about to execute, if its whenneeded= 
   attribute is set, but its is-needed flag is not, then delay 
   execution. Calling markNeeded() on a script that has a whenneeded 
   boolean but that has not executed yet first causes the markNeeded() 
   method on all the script's dependencies to be called, and then causes
   this script to become ready to execute.

 script id=jquery src=jquery.js async whenneeded/script
 script id=shims src=shims.js async whenneeded/script
 script id=myscript dependencies=shims jquery src=myscript.js 
 async whenneeded/script

   This would download jquery.js, shims.js, and myscript.js ASAP, and then 
   wait for further instructions.

 document.getElementById('myscript').markNeeded();

   This would then cause the scripts to execute, first jquery.js and 
   shims.js (in any order), and then myscript.js. If any hadn't finished 
   downloading yet, it would first wait for that to finish.

   (We could make markNeeded() return a promise, too.)

Is there a need for delaying the download of a script as well? (If so, we 
could change whenneeded= to have values, like whenneeded=execute vs 
whenneeded=download or something.)

Is there something this doesn't handle which it would need to handle?

-- 
Ian Hickson   U+1047E)\._.,--,'``.fL
http://ln.hixie.ch/   U+263A/,   _.. \   _\  ;`._ ,.
Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'


Re: [whatwg] Script preloading

2013-07-09 Thread Kyle Simpson
This is a long and complicated topic with lots of history. Please bear with 
the length of my reply.


 It seems that people want something that:
 
 - Lets them download scripts but not execute them until needed.
 - Lets them have multiple interdependent scripts and have the browser
   manage their ordering.
 - Do all this without having to modify existing scripts.

I think it's important to note that the primary motivation here is performance. 
If all I cared about was serial loading (and the performance of that was 
irrelevant), I could, with today's mechanisms, load one script at a time, only 
when I was ready to execute it, and if there were multiple scripts, do so in 
the correct order.

The fly in in the ointment is if I need to load multiple scripts at once, 
specifically if those come from different locations (one is jQuery from the 
CDN, another is a plugin from my server), and for performance reasons I want 
these scripts to load in parallel, but their execution order still matters.

Now, if THAT was the only concern, the new (well, 2 years old now) 
`async=false` (or, as I call it, ordered async) mechanism would be enough. 
But it's not.

Because there's only one ordered async queue, which means all such scripts 
have to go into the same bucket, and it's all or nothing for preserving 
execution order. What if I want to load jQuery, then I want (in ASAP order) for 
4 independent plugins to run?

Ordered async will run jQuery, then each plugin in request order, which might 
make one small plugin wait much longer than it needs to for an earlier plugin. 
Here, it's a performance issue because a plugin like a calendar widget might 
not appear and render as early as it could otherwise, because some other 
non-related plugin is coming from a slow location but was requested first.

Very quickly, ordered async starts to not be sufficient for various 
use-cases. It's like the 75% solution, but the 25% are still a concern, 
performance wise.



 I must admit to not really understanding these requirements (script 
 execution can be made more or less free if they are designed to just 
 expose some functions, for example, and it's trivial to set up a script 
 dependency mechanism for scripts to run each other in order, and there's 
 no reason browsers can't parse scripts off the main thread, etc). But 
 since everyone else seems to think these are issues, let's ignore that.

In an ideal world, we could tell everyone hey, there's a new mandate, rewrite 
all your code by XYZ deadline. Kthxbai. That's not how it works. The fact is 
that the web platform and the browsers move MUCH quicker than legacy content.

This is, and always has been, a question of if you think we should just wait 
around for years and years until every script we care about (but don't control 
since we didn't author it) gets rewritten, and while that's happening, web 
performance in this area just can't be addressed? I maintain still that we can 
and should fix the platform so we have more options than just tough luck.



 The proposals I've seen so far for extending the spec's script preloading 
 mechanisms fall into two categories:
 
 - provide some more control over the mechanisms already there, e.g. 
   firing events at various times, adding attributes to make the script 
   loading algorithm work differently, or adding methods to trigger 
   particular parts of the algorithm under author control.
 
 - provide a layer above the current algorithm that provides strong 
   semantics, but that doesn't have much impact on the loading algorithm 
   itself.
 
 I'm very hesitant to do the first of these, because the algorithm is _so_ 
 complicated that adding anything else to it is just going to result in 
 bugs in browsers. There comes a point where an algorithm just becomes so 
 hard to accurately test that it's a lost cause.

Can you please elaborate on how either of the two prominent proposals that 
Nicholas Zakas and I detailed years ago here are insufficient in that they fall 
into your first category?

http://wiki.whatwg.org/wiki/Script_Execution_Control

My proposal was to standardize what IE4-10 did, which is to start loading a 
script even if it's not in the DOM, but not execute it until it's in the DOM. 
Then, you monitor an event to know if one or more scripts have finished this 
preloading, and then you can decide if and when and in what order to add the 
corresponding script elements to the DOM to allow execution to proceed.

The spec already suggests the core of this:

For performance reasons, user agents may start fetching the script as soon as 
the attribute is set, instead, in the hope that the element will be inserted 
into the document. Either way, once the element is inserted into the document, 
the load must have started. If the UA performs such prefetching, but the 
element is never inserted in the document, or the src attribute is dynamically 
changed, then the user agent will not execute the script, and the fetching 

Re: [whatwg] Script preloading

2013-07-09 Thread Garrett Smith
On 7/9/13, Ian Hickson i...@hixie.ch wrote:

 A topic that regularly comes up is script loading.

Yes, for years it has come up.

I jumped on the topic around 2009 here and on comp.lang.javascript to
add the idea about chain of responsibility to this solution.

The chain of responsibility pattern is not new, and some examples
include FilterChain and in Apache ANT. The concept seems to apply well
to this context.

 I sent an e-mail responding to related feedback last year, though it
 didn't get any replies to the script loading parts of it:


 http://lists.w3.org/Archives/Public/public-whatwg-archive/2012Dec/0221.html

 It seems that people want something that:

  - Lets them download scripts but not execute them until needed.
  - Lets them have multiple interdependent scripts and have the browser
manage their ordering.
  - Do all this without having to modify existing scripts.

 I must admit to not really understanding these requirements (script
 execution can be made more or less free if they are designed to just
 expose some functions, for example, and it's trivial to set up a script
 dependency mechanism for scripts to run each other in order, and there's
 no reason browsers can't parse scripts off the main thread, etc). But

That is a good point and it is a good approach.

 since everyone else seems to think these are issues, let's ignore that.

 The proposals I've seen so far for extending the spec's script preloading
 mechanisms fall into two categories:

  - provide some more control over the mechanisms already there, e.g.
firing events at various times, adding attributes to make the script
loading algorithm work differently, or adding methods to trigger
particular parts of the algorithm under author control.

  - provide a layer above the current algorithm that provides strong
semantics, but that doesn't have much impact on the loading algorithm
itself.

 I'm very hesitant to do the first of these, because the algorithm is _so_
 complicated that adding anything else to it is just going to result in
 bugs in browsers. There comes a point where an algorithm just becomes so
 hard to accurately test that it's a lost cause.

 The second seems more feasible, though.

 Would something like this, based on proposals from a variety of people in
 the past, work for your needs?

 1. Add a dependencies attribute to script that can point to other
scripts to indicate that execution of this script should be delayed
until all other scripts that are (a) earlier in the tree order and (b)
identified by this attribute have executed.

  script id=jquery src=jquery.js async/script
  script id=shims src=shims.js async/script
  script dependencies=shims jquery src=myscript.js async/script


Why limit depends to be used by only scripts to refer only to other scripts?

If you put link depends=idref on style then stylesheet evaluation
could be deferred, too.

I explained some cases about why this is desirable here:
http://lists.whatwg.org/htdig.cgi/whatwg-whatwg.org/2009-February/018435.html

The test cases I'd posted aren't live, but they did show some
confusion at the time regarding load order of resources. Surety of
misunderstanding seemed to be what caused the idea to be so
offhandedly dismissed.

This would download jquery.js, shims.js, and myscript.js ASAP, without
blocking anything else, and would then run jquery.js and shims.js ASAP,
in any order, and then once both have executed, it would execute
myscript.js.

 2. Add an whenneeded boolean content attribute, a markNeeded() method,

A disabled/execute was mentioned here, before:
http://lists.w3.org/Archives/Public/public-whatwg-archive/2013Apr/0158.html


  document.getElementById('myscript').markNeeded();


I'd rather call execute() than tell Mark he's needed.

This would then cause the scripts to execute, first jquery.js and
shims.js (in any order), and then myscript.js. If any hadn't finished
downloading yet, it would first wait for that to finish.

(We could make markNeeded() return a promise, too.)

Or use a callback. Blocking on resource loading is bad.
-- 
Garrett
Twitter: @xkit
personx.tumblr.com


Re: [whatwg] Script preloading

2013-07-09 Thread Kyle Simpson
 But I'd settle for anything, no matter how complex, as long as it actually 
 solves the many use cases. Your proposed option has potential, as long as 
 the missing event part is addressed.
 
 It seems to me that from an IE-perspective, the only missing piece is the 
 event itself.

Well, strictly speaking, IE4-10 had a suitable event already, as you surely 
know. Unfortunately, IE11 has, currently, removed those event handlings, as 
they are non-standard. I wrote this blog post a few days ago begging the 
IE11 team to bring them back:

http://blog.getify.com/ie11-please-bring-real-script-preloading-back/

I know it was passed on to at least a few of the decision makers there, but 
I've not heard anything official in response yet. Any update? :) As it stands, 
the IE version of real preloading is in limbo and in danger of dying, as it's 
quite neutered without some event.

IF we could act quickly enough to standardize some preloading approach, even if 
that were different than how IE did it before, *maybe* it could make it into 
IE11 before final release? I dunno.



 Just one final side note on the above linked-to proposals (Zakas's and 
 mine). Over 2 years ago, I implemented feature-detects in LABjs script 
 loader for both of those proposals. Of course, the `readyState` one actually 
 works in IE4-10 and works beautifully I might add. In head-to-head loading 
 tests I've done from time to time, the IE real preloading mechanism often 
 beats out the good-but-not-great ordered async of the other modern 
 browsers.
 The `preload` one doesn't currently work of course (it's just dormant code 
 for now), but I thought it to be a sufficiently good enough proposal, and 
 likely enough to eventually happen, that I put in those few lines of code to 
 LABjs, as speculative future-proofing.
 
 The LABjs source code uses a feature-detect for the real preloading by 
 looking for the existence of the preload Boolean DOM attribute. After 
 thinking about it for a bit, I'm not sure I understand why that attribute is 
 necessary. 

I believe the reason that Nicholas suggested that the attribute needed to be 
there was two-fold:

1) he was concerned about the implicit nature of IE's behavior by sort of 
indirectly preloading simply by developer non-action (not inserting into the 
DOM).

Adding a positive attribute to a tag to say yes, I want this 
preload-and-defer-execution behavior was certainly more explicit, and opt-in, 
and thus maybe more attractive, since it had perhaps less potential to create 
accidental problems for legacy content or developer ignorance.

2) it makes for a simple/effective feature-detect. :)


Whatever mechanism we do have, we need a feature detect for it, obviously. 
`preload in document.createElement(script)` is nice and clean and semantic.

The IE way, I detect by looking at the readyState and noticing its initial 
value, which was an IE only behavior. Opera was the only other browser to 
support `script.readyState` (but NOT support the actual preloading concept), 
but Opera's version of the property has a different initial value.

I asked an Opera developer specifically and he asserted that Opera would not 
ever have an occasion to change that initial value to the same as IE's unless 
they were also matching IE's preloading behavior. Thus, we avoided (tenuously, 
in the absence of standards) any false-positives on that feature detect.



 If I were to only introduce the event handler (onpreload) it seems to address 
 the use cases, but then your 2+ year old dormant code would stay dormant :( 

I'm not nearly as concerned about dormant code staying dormant forever. I 
made the judgement call back then that the extra ~100 gzip-bytes were worth 
it if a future day ever came that it just magically worked.

I'd love it, for LABjs' sake, if whatever was standardized was one of the two 
approaches, either one.

But even if we standardized a third option, and I had to change LABjs, that 
would be FAR BETTER in my mind than never addressing this use case at all, 
especially in light of IE11 sort of retreating on this topic (either 
intentionally or not).





--Kyle






Re: [whatwg] Script preloading

2013-07-09 Thread Bruno Racineux
I just joined the list and glad this subject is brought up.
I have been wrestling pretty hard with script loading issues lately. I'd
say that having the browser manage script interdependency is probably a
bad and cumbersome way to solve these issues. I'll try to explain,
talk about the defer approach, as well as critical IE bugs that relate
to this very subject.

I think one of the reason that people may ask for this Interdependency
feature,
is due to the weakness of the platform they use, its plugins or the poor
management of such script (with often poorly conceived plugins not takign
dependency into account), which too often has the approach of loading all
scripts at all times regardless of the page context.

What's important to keep in mind, is that if you must have the browser
managing the interdependency, by association, you also have to manage it
at the app/platform level properly in the first place. Which seems awfully
redundant... And would probably lead to more page bloat or bad programming
habits.


As Kyle Simpson said, the primary motivation here is performance. Putting
scripts at the bottom, while preserving the scripts order has performance
drawbacks.
And 'async', while good for independent scripts such as social media apis,
is not really a good tools for dependency management.

My main issue against using external script loaders like LABjs and others,
has always been that if the browser must download a script first, before
starting to download the dependencies. It presents a drawback already, for
delayed the scripts by the script loader's latency and download time (at
least for the first uncached page load) similarly to having scripts at the
bottoms.

What we truly want is keep the order while loading script in a
non-blocking way.

Why not simply load all such scripts early in the head with 'defer',
which preserves the dependency order as determined by your app. Using
'defer' in head scripts is actually a very good way to preserve script
order with non-blocking scripts. And by loading the scripts very early in
the head, the possibility of a incurred significant delay of
DOMContentLoaded, for an eventual large script not yet downloaded, is
minimal to none.

In that sense, I think that too much focus has been placed on 'async',
with 'defer' having been extremely overlooked as such an adequate method
to non-blocking script loading with dependencies preserved. 'defer' after
all, is partly designed to guarantees that scripts execute in the order
they were specified and be delayed until document.readyState = interactive;

I sadly know there is a big hurdle for using 'defer' right now with
interdependencies, mainly with this IE9 bug
http://bugs.jquery.com/ticket/11310
Debunked in further details here (coincidentally, in part by Kyle Simpson):
https://github.com/h5bp/lazyweb-requests/issues/42


And may I get into further IE hate when it comes to the 'interactive'
state inconsistencies, by pointing to this very recent bug report I've had
to file:
https://connect.microsoft.com/IE/feedback/details/792880/document-readystat
e-interactive-firing-too-early-misfiring-in-ie11-9-and-10

Or should I beg the question, as to why it took my initiative yesterday
after almost a year of the problem being reported by others on github in
multiple occasions, to have this looked at so that IE11's final release
get it right, or not, who knows...

This problem exist since IE7! Is that really the best Microsoft can do?

There is something really wrong with the fixing process here. That, or too
big of a disconnect between those who test and those who are supposed to
fix things.
Or it is that developers are too fed up with those bugs, having to find
ways around them, to find the energy to report them appropriately?

Thankfully, the IE7-9 'defer' bug is has been fixed in IE10. Yet it's
likely postponing proper use of 'defer' for another what? 5 years?. Thanks
to Microsoft once again for holding the internet back and make our life
harder? Is that all we can come up with?

I would actually advocate to petition Microsoft to release patches for
IE8, IE9 and IE10 for these particular stupid overlooked bugs, which some
days honestly make me want to kill myself.

I understand that in some areas, older browsers cannot add or remove
features to the same major release for good reasons. But it's a real
problem if bugs of this kind ( which wouldn't break any site if fixed
now), cannot be fixed on older browsers using regular Windows updates. The
idea that a browser is set in stone on release, and cannot be touched
become a real issue to progress. Aren't those two particular bugs good
example of thing that should be fixed and applied along security patches?
And not have to wait 5 to 10 years coping with buggy browsers for no good
reasons I can think of.


I would also strongly favor restoring the previous spec portion of 'defer'
which allow to have defer on inline script blocks (i.e. if the src
attribute is not present). I don't know 

Re: [whatwg] Script preloading

2013-07-09 Thread Kyle Simpson
 I have been wrestling pretty hard with script loading issues lately. I'd
 say that having the browser manage script interdependency is probably a
 bad and cumbersome way to solve these issues.

What do you mean by having the browser manage script interdependency? As far 
as I am aware, this thread and these feature requests are not about the browser 
managing script interdependencies… in fact, quite the opposite. What we're 
asking and hoping for is a facility that allows the app code to manage the 
dependencies and the loading order, while only relying on the browser to do the 
actual loading for us the way it always has.

The only part of that puzzle that's missing is a way to tell the browser to 
pause between finishing-loading and starting-executing. Asking for such a 
mechanism has really nothing to do with offloading dependency management to the 
browser to handle. It's empowering the app code to be more in control, not less.



 I think one of the reason that people may ask for this Interdependency
 feature,
 is due to the weakness of the platform they use,

Again, I think you may possibly be misunderstanding the goal of what's being 
asked for. But I'll agree with you that there's a weakness. The weakness, IMO, 
is in the web platform itself, in not giving us more fine-grained control over 
script loading. That is why we keep having this discussion every 6 months or so 
for the least several years. The use-cases never go away, and the hacks we use 
to deal with them never get any less ugly.



 And 'async', while good for independent scripts such as social media apis,
 is not really a good tools for dependency management.

Again, possibly a case of misunderstanding or missed context from previous 
conversations. When I bring up async, I'm not talking about script async in 
markup as you suggest, but actually `script.async = false` being set on 
dynamcially created script elements (in code). async=false (aka ordered 
async) is a relatively new feature added to the platform about 2.5 years ago 
that gives us async parallel loading, but the browser automatically enforces 
execution order to be request order, instead of ASAP order.

async=false is actually a good feature. The problem is not the feature 
itself, but that it's only part of what we needed.



 My main issue against using external script loaders like LABjs and others,
 has always been that if the browser must download a script first, before
 starting to download the dependencies. It presents a drawback already, for
 delayed the scripts by the script loader's latency and download time (at
 least for the first uncached page load) similarly to having scripts at the
 bottoms.

For LABjs' part, I never suggest to people to load LABjs in a separate file. I 
suggest that people use a bootstrap type code file, which would be a single 
.js file they load with a single script tag in their markup, and it contains 
all the bare-minimum code necessary to bootstrap the page/app. It would include 
the code for LABjs, also the $LAB chains for loading other scripts, even basic 
event handling or other bootstrap type logic.

Moreover, the extra ~2k of gzip-bytes that LABjs costs (even if it's a 
separate file, but especially if it's included in another bootstrap file) is 
almost always made up for in savings by being able to take advantage of 
consistent parallel loading of scripts.

If your page only has 3-5k of JS on it, then you shouldn't use a script loader. 
But if you're like most sites, and you're loading 100-300k of JS, then a tiny 
2k of JS for loading optimization is not even a drop in the ocean.

Lastly, I advocate the techniques of deferring certain parts of your scripts to 
not loading during page-load at all, but instead post-loading or on-demand 
loading at later times. This amounts to needing to have the ability to do 
dynamic loading during the lifetime of the page. Markup alone is never enough 
for that. You have to have a script loader of some sort.

So, I advocate that a tiny but powerful script loader that you use for BOTH 
uses is a win. You use the same script loading techniques for page-load loading 
as you do for on-demand loading. Consistency of toolset here makes coding and 
maintenance easier in the long run.


 Why not simply load all such scripts early in the head with 'defer',

As you mention below, defer is horribly buggy and unreliable. The chances of 
IE8+ (not to mention IE6-8) being patched to have better defer are roundable to 
zero.



 'defer' in head scripts is actually a very good way to preserve script
 order with non-blocking scripts.

But it only works for external scripts (as you note below), and it only works 
for markup loading during page-load, and gives no answer for dynamic/on-demand 
loading later. As such, by design, it's insufficient for the use-cases 
presented.



 I would actually advocate to petition Microsoft to release patches for
 IE8, IE9 and IE10 for these particular stupid overlooked bugs