> 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.


* "ex2-jaffathecake.js" is again my attempt to address this use-case using 
Jake's proposal. The major outstanding question here is how `dependencies` will 
respond to loading errors. It's unclear, thus far, how much sensitivity (if 
any) this mechanism would have to loading (network) errors, compile-time 
(syntax) errors, and run-time errors. The less sensitive it is, the more 
complex this code needs to be made to handle those use cases.





--Kyle



Reply via email to