[whatwg] Proposal for separating script downloads and execution

Kyle Simpson getify at gmail.com
Wed Feb 9 07:06:13 PST 2011


?
> Mighty conjecture, chap. Multithreading is even possible on
> microcontrollers like the Atmel ATmega32 ? so why should a modern
> operating system running on reasonable hardware not be able to do it?

In most mobile devices I've had the exposure to developing for, 
multi-threading is not possible/available to me. The usual answer, for 
instance for the iPhone, is that true multi-threading will tend to cause 
serious drains on limited battery life, which degrades quality of 
user-experience and user satisfaction. That's the only "anecdotal" evidence 
that I have for how these engines may not be completely free to multi-thread 
as is being suggested.

In any case, you're still missing the point. The mobile OS's (and even the 
JavaScript engines) are of course free to improve their internal 
implementation details, but this HTML spec has only a slight modest ability 
to affect that. The hardware/mobile-OS vendors have dozens of different 
pressures that play into what they can and cannot implement, and how. Even 
if the HTML spec were to say "must process script execution in a separate 
thread from the rendering engine", the feasibility of that requirement may 
still be overshadowed by lots of factors completely out of the control of 
the specification group.

We can continue to debate what might be nice for mobile vendors to consider, 
but they aren't on this list and listening to us. Who IS on this list, and 
who IS interested, are developers who have real performance problems right 
now. And they are creating ever more complex hacks to get around these 
problems. And the spec has an opportunity to make a small foot-print change 
to give them some better options for that performance negotiation.

You're also ignoring the fact that there are several other documented 
use-cases for execution-deferral that are not related to mobile (or 
multi-threading) at all. That maybe the 80% use-case for this proposal, but 
it's certainly not the only reason we want and need a feature like this.


> Fun fact: I use mobile versions of some web sites, because they are much
> quicker, even on the desktop. Sometimes a little minimalism can go a
> long way.

We're not particularly talking about generalized web sites as much as we are 
talking about complex mobile web applications like Gmail. Even in their 
minimalism, the bare minimum experience they're willing to deliver is 
overloading the mobile browser and so they are resorting to crazy and 
brittle hacks.

In my opinion, when we see a trend toward developers having to hack around 
certain parts of the functionality that don't work the way they need it to 
(for real-world use-cases), then it's a good sign that we should consider 
helping them out. And suggesting that they just load less JavaScript is not 
really all that helpful for the population of applications that are most in 
need of this feature.


> Counter-intuitive at first, but true: More complex code is not
> necessarly faster code. More options are more options to screw up.

We have a number of well-known and well-documented experts in the realm of 
page-load optimization and script loading functionality who are behind 
requests like is being discussed. If we can't trust them to do correctly 
with what we give them, then the whole system is broken and moot. The fact 
that some developers may misunderstand and improperly use some functionality 
should not prevent us from considering its usefulness to those who clearly 
know the right things to accomplish with it.

It also hasn't been shown with any degree of specificity just what the fear 
is of developers "screwing up" if we give them this functionality. Right now 
it's a bunch of conjecture about possible misunderstandings, something which 
should be easy to deal with through proper documentation, education, and 
evangelism. Why are we so afraid to let the right implementations of a 
functionality flourish and bubble to the top, and drown out the wrong 
implementations of functionality by those are are either ignorant or 
incompetent?


> I'm losing track in the noise of what the fundamental disagreements 
> are--if
> there even are any.  I think the original proposal is a very good place to
> start

The original proposal is in fact more focused on the markup-driven use-case 
than on the script-driven use-case. The original proposer, Nicholas, agreed 
in an earlier message that he's really more concerned with script-driven 
functionality than markup driven functionality. And I completely agree with 
that assertion.

In fact, I'd go so far as to say that the use-case for separating script 
loading from its parsing/execution phase (and thus being able to 
control/trigger when that phase occurs, later) is 99% driven by the 
script-loaders use-case. Script loaders by and large do not use markup 
semantics to accomplish their tasks (because most of them do not use 
document.write("<script...."); to load scripts)

So, if we consider the spirit of the original proposal, we should examine it 
in the proper context (the vast majority use-case), which is script elements 
being created from script logic rather than markup.

Given that proper context, the proposal becomes something like:

1. Give a dynamic script element a "noExecute" property (a boolean property, 
defaults to false, can be set to true)
2. Give a dynamic script element an "execute()" function which executes a 
script that has been "deferred" by the "noExecute" property.

The problem with *that* phrasing of the proposal (compared to the 
"readyState" preoloading I'm advocating) is:

1. It asks for two new unprecedented additions to the script element 
specification. The other proposal asks to take the existing spec wording and 
change it from a "may" to a "must" (from suggestion to requirement).

2. It has no existing browser support. The "readyState" proposal also 
suggests we take the precedent of "readyState" property and the associated 
"onreadystatechange" handler, from say XHR, and apply it to script elements, 
something which one browser vendor (IE) has already done, and at least one 
other browser vendor has said they could/would do (Opera).

In other words, the "readyState" proposal tries to address the needs of the 
use-case using existing precedent and existing spec content as much as 
possible, AND it has already some browser vendor support. "noExecute" has 
neither of those two things, and so has a tougher uphill battle to winning 
adoption.


> - Just for comparison: <script src="path.js" noexecute
> onload="this.execute()">

Several times that code snippet has been suggested in this thread, and each 
time a fundamental problem is being overlooked. The way the "onload" event 
CURRENTLY works is that it doesn't fire until after a script has finished 
executing. There's no way we can change the semantics of "onload" now to be 
run before the script executes (like when it actually finishes loading), 
even though that clearly would be the more semantic way for that event to 
work.

As stated there, `onload="this.execute()"` will never execute because of 
chicken-and-the-egg.

So, we'd actually be forced to add yet another event/property to the script 
element (either in markup or in script) that was called "onfinishloading" or 
"onloaded" (probably confusing alongside "onload") or something like that. 
And *that* is conceptually pretty similar to my proposal for utilizing the 
precedent of the "readyState" event progression, which has a "loaded" event 
in it.


> The link tag is meant to support a "prefetch" value for the "rel" 
> attribute asking to preemptively cache the resource:
> - http://blog.whatwg.org/the-road-to-html-5-link-relations#rel-prefetch
> - http://davidwalsh.name/html5-prefetch

For <link rel=prefetch> to address the use-case, some event mechanism would 
HAVE to be added to the <link> tag such that the finishing of that 
"prefetching" could be detected. But then what do we do once it's finished 
loading, even if we *do* add some <link> event mechanism to detect it?

.execute() would be a terrible idea for <link>, because it would essentially 
morph <link> into a <script> element at that point. Not only is this 
significantly more confusing to web authors for that type of behavioral 
overloading, but I'd guess that all the complicated semantics around the 
<script> element would then have to be duplicated into a <link> tag that is 
being executed.

It's tempting to suggest that you would then just add a proper <script> 
element with the same URL to accomplish the "execution" of it. This suffers 
a similar fate to many of the hacky workarounds that currently exist: that 
it's based on the assumption that the resource was cached.

Lots of resources are loaded/executed and never cached (either on purpose, 
or by fault of improper headers). So, this "cache preloading" technique, 
however we try to enable it, will always be flawed by that assumption, an 
assumption which if it fails, causes a very costly double-load of the 
resource.

Two other problems with this <link rel=prefetch> idea:
1. The current spec wording around <link rel=prefetch> is clearly that that 
its just a "hint" to the browser that it should fetch that resource at some 
point in the future. The use-case calls for a decisive/determinate mechanism 
(like the existing script element) whereby the author can express "I need 
you (browser) to load this as soon as possible" as opposed to the semantics 
of <link rel=prefetch> which are more like "I think it would be a good idea, 
if you get some time, to load this resource, but only if you feel like you 
should, at some undetermined time in the future."

For <link rel=prefetch> to be useful to the use-case, it would need to have 
that spec wording changed to be a lot more direct about the resource needing 
to be loaded with a much higher priority on the "now" of it. Of course, no 
load is guaranteed to start right away, but there's an important difference 
between "please load asap" and "you can load whenever you feel like it".

2. The majority use-case is, as stated above, for script loaders (in script 
logic) to be able to "preload"/"prefetch" script elements. AFAIK, <link 
rel=prefetch> isn't defined for script-inserted <link> elements, and it 
certainly (upon testing) isn't supported well in browsers. Clearly, <link 
rel=prefetch> is much more tuned to the vast minority use-case, of 
markup-driven loading.

Even if we did force that <link rel=prefetch> be functional from 
script-driven code, it would look a WHOLE LOT like what the "readyState 
preloading" proposal already looks like, except it'd be more confusing 
because it'd involve two different elements instead of just one.


--Kyle
 




More information about the whatwg mailing list