<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>getiblog &#187; loading</title>
	<atom:link href="http://blog.getify.com/tag/loading/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.getify.com</link>
	<description>javascript, performance, and ui musings</description>
	<lastBuildDate>Thu, 15 Dec 2011 17:37:04 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=</generator>
		<item>
		<title>Mozilla &amp; LABjs&#8230; part 2</title>
		<link>http://blog.getify.com/mozilla-labjs-part-2/</link>
		<comments>http://blog.getify.com/mozilla-labjs-part-2/#comments</comments>
		<pubDate>Thu, 07 Oct 2010 17:12:49 +0000</pubDate>
		<dc:creator>getify</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Performance Optimization]]></category>
		<category><![CDATA[FF4]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[labjs]]></category>
		<category><![CDATA[loading]]></category>
		<category><![CDATA[mozilla]]></category>
		<category><![CDATA[optimization]]></category>
		<category><![CDATA[order]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[script loader]]></category>

		<guid isPermaLink="false">http://blog.getify.com/?p=591</guid>
		<description><![CDATA[This post is the immediate &#8220;part 2&#8243; follow-up to Mozilla &#38; LABjs: the story unfolds. Definitely read that before proceeding to read here. As I mentioned at the beginning of that previous post, I am writing to address the points raised in the comment by the Mozilla developer who was responsible for the change in [...]]]></description>
			<content:encoded><![CDATA[<p>This post is the immediate &#8220;part 2&#8243; follow-up to <a href="http://blog.getify.com/2010/10/mozilla-labjs-the-story-unfolds/">Mozilla &amp; LABjs: the story unfolds</a>. Definitely read that before proceeding to read here.</p>
<p>As I mentioned at the beginning of that previous post, I am writing to address the points raised in the <a href="http://blog.getify.com/2010/10/ff4-script-loaders-and-order-preservation/comment-page-1/#comment-748">comment by the Mozilla developer</a> who was responsible for the change in script-load-order behavior. I already responded in part 1 to the overal condescending (in my opinion) tone of that comment, but here I will address very specific points made.</p>
<h3>Dive in</h3>
<blockquote><p>That&#8217;s not a safe data point to draw forward-looking expectations from. IE and WebKit haven&#8217;t executed script-inserted external scripts in insertion order. When two browsers do one thing and two other do another thing, it should be no surprise to anyone that when standardization happens, at least two browsers need to change their behavior to comply.</p>
<p>I can&#8217;t stress this enough: When you see that one set of browsers do one thing on a given point and another set of browsers does something else on the same point, you shouldn&#8217;t assume that these two sets of browser will retain differing behaviors forever.</p>
<p>When you see one set of browsers doing one thing and another doing another, UA sniffing (LABjs doesn&#8217;t sniff the UA string but it sniffs &#8220;Gecko&#8221; from the presence of MozAppearance) is exactly the wrong thing to do.</p></blockquote>
<p>I addressed this point in the <a href="http://blog.getify.com/2010/10/mozilla-labjs-the-story-unfolds/">previous post</a>, but let me reiterate: It&#8217;s not my fault the browsers have carelessly left these doors wide open. I was not content to sit on the sidelines and wait for years while web performance optimization remained impossible to grasp. So I jumped into the fray and solved the use case based on what we have now.</p>
<p>I&#8217;m not so naive as to believe the landscape of browsers and features will never change. That&#8217;s not the point of my complaint. <strong>The whole point of my complaint with Mozilla (and with ill-conceived/short-sighted standards you&#8217;re falling back on) is that if you&#8217;re going to change behavior, you have to engage the community actively, especially the community that&#8217;s most affected.</strong></p>
<p>LABjs is, I think fair to say, pretty well known at this point, and it&#8217;s not unreasonable to think that Mozilla could have done some google searches to see if there were any well-known or widely-used tools that may be affected by the change. Certainly LABjs would have come up somewhere in the first page or two of some of those searches.</p>
<p>I fully expect browsers to change and get better, but what <em>must</em> also happen is that the browsers must engage the community to see what the needs are. Mozilla has a <strong>GREAT TRACK RECORD</strong> in the community of this in the past. But the handling of this particular issue, I think was not up to that same &#8220;standard&#8221;.</p>
<p>What I would have hoped for, and what I hope for still, is that Mozilla will proactively try to address the valid and already existent use cases when they make a change to behavior. If you can&#8217;t support the behavior any more, give us a way to definitively detect the change (so we can still support backwards in your browser family) and also give us some alternative that still serves the use-case. Callously claiming that the use case is not valid (or even &#8220;may not be&#8221;) is not a way to endear you to the members of the community.</p>
<blockquote><p>The right thing to do is to do something that works without browser sniffing in all current browsers. For cross-origin script library loads this means designing the script libraries in such a way that the act of evaluating a given library doesn&#8217;t cause the library to call into another library but only makes the API of the script available such that only calling the API potentially causes a cross-library call. (Yes, I&#8217;m saying that in the current environment, that LABjs probably shouldn&#8217;t have tried to provide cross-origin ordered loading of external scripts given that it couldn&#8217;t be provided without either UA-sniffing or making dangerous assumptions about the caching relationship of loads initiated by object/img elements and loads initiated by script elements.)</p></blockquote>
<p>This is an absurd assertion to make. I don&#8217;t consider it a valid option to just say LABjs should never have happened because the browsers and standards didn&#8217;t have a solution. Would you say the same thing to Steve&#8217;s face: &#8220;Steve&#8230; stop trying to improve the web performance optimization of scripts loading, because it&#8217;s not possible to do so yet.&#8221; That&#8217;s ludicrous.</p>
<p>LABjs is a self-admitted and proclaimed <strong>gap technology</strong>. It&#8217;s designed to meet an interim (and backwards-compatible) need &#8212; the need to drastically improve web performance optimization by parallel loading of scripts. And moreover, the need to normalize that behavior across ALL web browsers, not just the newest generation and ignore web performance for the older ones.</p>
<p>My hope always has been, and continues to be, that LABjs is someday made moot and unnecessary because all the browsers figure out a common way to handle things that serves all these use cases and needs in a performance-savvy way. And I spend countless hours and effort trying to advocate for such. It&#8217;s obviously frustrating when, either directly on purpose or just be accident, one browser vendor throws all that effort into jeopardy. That&#8217;s why I&#8217;m reacting with the candor that I am.</p>
<p>I continue to hope an amiable solution can be found. I hope that Mozilla is committed to the same. But chastising me on &#8220;right&#8221; and &#8220;wrong&#8221; like a little school boy and then offering no valid alternative is quite disingenuous.</p>
<blockquote><p>The plans have been <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/scripting-1.html#running-a-script" rel="nofollow">on display</a> in the cellar of the planning office for at least nine months.</p></blockquote>
<p>I&#8217;ve read this spec section many times. Just now reading it again, I found the one phrase which I&#8217;d missed in terms of interpretation on dozens of previous readings. &#8220;The element must be added to the set of scripts that will execute as soon as possible.&#8221;</p>
<p>I want you to notice something about that phrase. It&#8217;s a little bit ambiguous. At least from my perspective. It says that once a script loads, it should &#8220;execute as soon as possible&#8221;. But it doesn&#8217;t explicitly say that &#8220;as soon as possible&#8221; means to the exclusion of other previous dependencies.</p>
<p>If the interpretation of that phrase is that &#8220;as soon as possible&#8221; should be ignorant of things like previous dynamic scripts (insertion-order wise), then I submit to you that <strong>standard is wrong</strong>. It&#8217;s wrong because doing so completely ignores the use case of dynamically loading in parallel but preserving order &#8212; a use case that&#8217;s overwhelmingly self-evident for anyone who&#8217;s built web pages with more than one script file (like jquery and a single jquery plugin, for instance). We can have order preservation if the script tags appear in the HTML, but we can&#8217;t have order preservation if they are injected? That&#8217;s beyond silly.</p>
<p>I&#8217;m glad I now see exactly where this bad spec writing/interpretation is based off of. Prior to now, I&#8217;ve been unable to see anything in the spec that remotely resembles the spec indicating proper behavior between multiple dynamic scripts. But I strongly assert that the spec is wrong (or incomplete) in that respect. And implementing a part of the spec that has ambiguous interpretation at best and doing so in a way that completely ignores other important and valid use cases and needs is, in my opinion, somewhat irresponsible.</p>
<p>So I&#8217;d say this: you have the right (and responsibility) to implement spec. But what if spec is wrong? What if the spec fails to address the needs of the community? Should you still implement it and just look the other way? I say, no. I say there needs to be more community comment and involvement. I&#8217;m sorry I wasn&#8217;t around and part of the prior discussions when that phrase was added and agreed to, but nevertheless, the spec is going to cause some seriously negative waves for a lot of us if its implemented as currently interpreted and only that.</p>
<blockquote><p>
&#8230;..jQuery&#8230;.. </p>
<p>So I was doing what the standard says in order to fix site breakage. That&#8217;s about as righteous as browser engine changes can be.</p></blockquote>
<p>Agreed. I&#8217;m glad you implement spec. No one is criticizing that. But implementing things which have other major negative side effects, or even just things which are open to possible other interpretations or further discussion, without engaging the community you will directly affect, is not what I&#8217;d call wise and prudent behavior.</p>
<blockquote><p>As for not engaging you, there were three reasons for not engaging you: First, I was unaware of you. (The Web is pretty big!) Second, I was in a hurry. Third, the change I was making made Gecko behave like WebKit and IE (well, not exactly apparently for the non-script type thing), so it was relatively safe to assume that sites wouldn&#8217;t break since sites on the Web usually are already taking IE-compatibility and WebKit-compatibility into account. Of course, such reasoning only works for estimating the breakage risk for sites that run the same code path in all browsers. If you UA-sniff, your code may break, so please, please, don&#8217;t UA sniff.</p></blockquote>
<p>&#8220;Unaware&#8221;. Ok fair enough. LABjs isn&#8217;t as popular as jQuery, nor do I work for Mozilla like John Resig does. But LABjs is not an obscure unknown project either. It&#8217;s on the radar of some pretty big sites, and dozens of other big sites have expressed curiosity in experimenting with it. It&#8217;s on a bunch of blogs, it&#8217;s in a bunch of JavaScript conference talks I&#8217;ve given&#8230; blah blah blah. I don&#8217;t think it&#8217;s unreasonable to assume that LABjs has enough presence that due diligence in the area of script loading and order preservation should have surfaced it on the radar.</p>
<p>&#8220;In a hurry&#8221;. Well, we all make our mistakes, right? Everything about LABjs has been the opposite of being in a hurry. The topic in general is so ridiculously over complex due to all the quirks, it&#8217;s prudent to do anything but be in a hurry about it.</p>
<p>&#8220;Gecko like IE/Webkit&#8221;. What about Opera? Opera has operated like you (preserving script order) for as long as I&#8217;ve been paying attention. Did you think that maybe there was a reason why Opera did it that way too? Did you consider the effects of abandoning that behavior and leaving Opera as the only odd-one out would do to the script-loader part of the commmunity? You yourself admit that you took one area to adhere to IE/Webkit, but other adjacent things (however right or wrong) you didn&#8217;t adhere to. This is a common truth &#8212; doing part of the work can sometimes be worse than doing none of the work.</p>
<blockquote><p>New Twitter works fine in Minefield. Vimeo seems to work on Mac. (There are problems on 64-bit Linux, but I&#8217;m guessing those are related to out-of-process plug-ins.) Zappos isn&#8217;t obviously broken, but I didn&#8217;t try to order anything from there.</p>
<p>In fact, so far, there&#8217;s been no reports of actual site breakage arising from the Gecko script loader change that&#8217;d have reached me.</p></blockquote>
<p>Referencing surface testing of the sites I mentioned and seeing no observed site breakage, and asserting that as evidence is a pretty weak &#8220;inference&#8221; to whether or not the site is or will be affected by the change. Why? Because I know specifically in those 3 sites cases, they are not <strong>yet</strong> using the &#8220;preloading&#8221; (they have that feature flag turned off). But they are all intending to use it in the near future. Again, as I&#8217;ve asserted before, LABjs is only useful when considered as a performance script loader for dynamic parallel loading and ordered execution. </p>
<p>When you turn off &#8220;preloading&#8221;, LABjs becomes a pretty dumb and useless script (in fact, sometimes less performant than the manual &lt;script> tags alternative). The only reason any of those sites heard about or care about LABjs is for its potential performance accelerations. Just serial on-demand script loading is pretty trivial and been done much better by others long before I came around.</p>
<p>It&#8217;s quite valid and defensible why these major sites are rolling out their LABjs support and feature-usage little-by-little. There&#8217;s various reasons for Twitter and Vimeo doing things as they are now. But I know and regularly communicate with their developer teams, and I&#8217;m actively working on helping them get to the next (and more ideal) level.</p>
<p>I can tell you unequivocally that if any of those sites were to enable &#8220;preloading&#8221;, they would immediately break in Minefield. What this means, if we can&#8217;t figure out a resolution, is that those sites may never be able to turn on &#8220;preloading&#8221;, which means they&#8217;ll probably be well advised to just abandon LABjs going forward.</p>
<p>Moreover, if you want actual sites that use LABjs that break in Minefield, take this blog site and also <a href="http://flensed.com">flensed</a> as two examples. Notice that if you load either of them in Minefield, some things break, like the code that does the Twitter feeds, etc. There are lots of other sites using LABjs with &#8220;preloading&#8221;, and 100% of them will break in Minefield. So if real world examples are in need, I&#8217;ll be happy to point more to you besides the two just mentioned.</p>
<blockquote><p>Since reports of concrete site brokenness are absent, could it be that sites aren&#8217;t actually relying on the in-order property that LABjs tries to provide?</p>
<p>Do authors actually need to? In practice that is. Aren&#8217;t libraries that one might want to load already designed so that they don&#8217;t have loading-time inter-dependencies if you wait until all the libs have loaded before calling the APIs they provide?</p></blockquote>
<p>No, again, unequivocally the opposite is true of the real world. It&#8217;s very rare that you see (even production) sites that will bundle all of jQuery and all of jQuery-UI and all of the dozen associated plugins for each, all into one file. What usually happens is they load jQuery and jQuery-UI both separately from the Google CDN location, and then they load one or two local scripts from their server that have all the plugins and their own site logic contained. This is far and away the more common use case for the majority of the internet. Only the most high-end traffic sites self-host such resources and package them all into a single file.</p>
<p>And no, it&#8217;s not reasonable to assume that all the scripts which are out there that DO currently have load-order dependency must all simultaneously be re-written because of one change made by one browser vendor. We have to be pragmatic and continue to support the way the web currently (and has for a long time and will for a long time) works.</p>
<blockquote><p>Am I inferring correctly that you wouldn&#8217;t want script-inserted scripts to block parser-inserted scripts?</p>
<p>Do you <i>really</i> want script-inserted external scripts to block script-inserted inline scripts and parser-inserted scripts? Or do you just want script-inserted external scripts to maintain order among themselves?</p></blockquote>
<p>Here&#8217;s what I don&#8217;t want: I don&#8217;t want an inserted script node to have <strong>any</strong> dependencies on anything else in the document, <strong>except</strong> other inserted script nodes.</p>
<p>I understand that jQuery&#8217;s use case for &#8220;global Eval&#8221; uses inserted &#8220;inline&#8221; scripts and that the blocking of such logic is undesired. I think there should be some sort of flag settable on such scripts to inform the browser of the need for immediate execution.</p>
<p>But I have a completely different use case, one that is extremely common on the majority of the web. It is that people often times will have what I call &#8220;script tag soup&#8221;, which is that they will have several script tags (external src references) and then an inline script tag with some logic, and then possibly more external script tags and then more inline script tags, etc. They have these tags strewn all over the HTML source (for various reasons, including CMS&#8217;s, templating limitations, etc).</p>
<p>Steve Souders gave a term for the idea of replacing an inline script block with something that would execute in the proper order after a dynamic script was loaded&#8230; it&#8217;s called &#8220;coupling&#8221;. LABjs&#8217; entire stated goal is to replace &#8220;script tag soup&#8221; with dynamically loaded (and yes, if need be, properly &#8220;coupled&#8221;), script loading alternatives. For instance, this blog post I did late last year on <a href="http://blog.getify.com/2009/11/labjs-how-to-deal-with-inline-code/">using LABjs to deal with inline script blocks along side dynamically loaded external resources</a> shows such a common usage pattern.</p>
<pre class="code">
&lt;script src="framework.js">&lt;/script>
&lt;script src="myscript.js">&lt;/script>
&lt;script>
  myscript.init();
&lt;/script>
&lt;script src="anotherscript.js">&lt;/script>
&lt;script>
  another.init();
  framework.init();
  framework.doSomething();
&lt;/script>
</pre>
<p>To use LABjs to deal with that &#8220;script tag soup&#8221; (both the external dynamic loadings and the &#8220;coupled&#8221; inline scripts), you do this:</p>
<pre class="code">
&lt;script>
  $LAB
  .script("framework.js")
  .script("myscript.js")
  .wait(function(){
     myscript.init();
  })
  .script("anotherscript.js")
  .wait(function(){
     another.init();
     framework.init();
     framework.doSomething();
  });
&lt;/script>
</pre>
<p>So, I&#8217;d say, <strong>yes</strong>, &#8220;coupling&#8221; of inline scripts to execute in the proper order along with externally loaded scripts is very important.</p>
<p><strong>HOWEVER</strong>, this issue is quite confused, because LABjs does not actually use injected inline scripts to handle how this &#8220;coupling&#8221; works. Because a function is passed to the .wait() function, that function can simply be executed with no need for an inserted inline script node.</p>
<p><strong>ON THE OTHER HAND</strong>, LABjs does in fact do some &#8220;inline script insertions&#8221; for some browsers (not Mozilla). For <strong>local scripts</strong> that are preloaded in IE/Chrome/Safari using local XHR, those scripts are executed at the proper time in the chain by creating an inline script node and injecting the loaded source code of the script into the node using the .text property.</p>
<p><strong>So, for THAT use case</strong> for IE/Chrome/Safari, I absolutely do hope that there&#8217;s still some way to make sure the injected code can execute right away when asked to, but I <strong>do not need</strong> to be able to inject that script node ahead of time and have the dynamic external scripts pay attention to it as far as order. As I said above, having an &#8220;execute immediately&#8221; flag (or behavior, as it currently seems) similar to jQuery&#8217;s &#8220;global Eval&#8221; use case would be more than sufficient.</p>
<p>To answer your question directly, I only want dynamically inserted script nodes to respect insertion order among themselves &#8212; nothing more. For Mozilla, I only use dynamically inserted external scripts, so for you guys, I don&#8217;t need the behavior of also preserving order with &#8220;inserted inline scripts&#8221;. But I do need the &#8220;immediate&#8221; execution of inline scripts for the other browsers&#8217; &#8220;preloading&#8221; tricks (for local files only) to keep working.</p>
<blockquote><p>This is exactly what&#8217;s happening. (Well, except the standard says &#8220;If the user agent does not support the scripting language given by the script block&#8217;s type for this script element, then the user agent must abort these steps at this point.&#8221;, so your bogus type trick doesn&#8217;t work according to HTML5.)<br />
&#8230;<br />
I now see that you posted to the WHATWG&#8217;s &#8220;help&#8221; mailing list in March. The WHATWG was already publishing a spec that covered the area and you didn&#8217;t ask for any changes, and you didn&#8217;t follow up to Hixie&#8217;s follow-up question, so the thread went nowhere.</p>
<p>To engage with browser vendors on this topic, I encourage you to join the W3C HTML WG. (There&#8217;s a better chance of engaging Microsoft there than on any of the WHATWG lists.)
</p></blockquote>
<p>As I asserted earlier, I have been tirelessly, for over a year, exploring how I can best advocate for practical standards to be written <strong>and</strong> implemented which are informed and aware of the various performance use cases that are at play. The attempts on the WHATWG mailing list, I was shot down immediately. I did follow up with several of those people in direct one-on-one emails, and overwhelmingly the response seemed to be &#8220;we don&#8217;t need standards for this&#8221;. They made no reference to the standard that was already there, they said no standard was needed. Obviously we do need it, so I considered that to be a brick wall. I only went to the WHATWG in the first place because someone suggested that it&#8217;d be a better place to address this topic than the W3C.</p>
<p>When WHATWG failed to be receptive to my call for a discussion, I then pursued another avenue. I have had several email exchanges with Brendan Eich and various others he CC&#8217;d (including some people from Yahoo, I believe) to try and get the discussion rolling. While the group seemed to be receptive to the need for such discussions, the discussions themselves have yet to go anywhere productive. It wasn&#8217;t a brick wall like WHATWG, but it&#8217;s yet to produce any useful results.</p>
<p>I even tried (a month ago) to join the new W3C Web Performance WG, again hoping that they would be a good platform to start pushing this discussion. I&#8217;ve yet to hear back from them on my application to join.</p>
<p>So, in the mean time, I&#8217;ve been continuing to advocate (via Twitter, blog posts, and conference speakings) for more awareness and action on this issue. I&#8217;ve done everything I can to make LABjs and the need for performance script loading as wide-spread known as possible. Steve Souders has endorsed LABjs on several occasions, and I believe he also would agree there&#8217;s need to come up with a standard everyone can agree on, <strong>as long as that solution doesn&#8217;t ignore the needs of the web performance community</strong>.</p>
<p>I have no problem with trying to also join the W3C. But please don&#8217;t accuse me (wrongly) of inaccurate claims in my saying that I&#8217;ve been pushing for advocacy and awareness on this topic in a lot of different avenues for quite awhile. I don&#8217;t have a very well known or influential voice, but I&#8217;m every bit (or more) passionate as anyone else on having a productive discussion with all the players so that a good solution can be found.</p>
<blockquote><p>It seems you aren&#8217;t too happy now that such standardization and implementation is happening <img src='http://getiblog.2static.it/wp-includes/images/smilies/icon_sad.gif' alt=':-(' class='wp-smiley' /> </p></blockquote>
<p>I&#8217;m only unhappy because the interpretation of spec as currently written seems to be ignorant of a very important and wide-spread use case, and because the process by which vendors like Mozilla are implementing that (in my opinion, ill-conceived) spec is not properly engaging the community (like myself) to make sure that important facts aren&#8217;t being bull-dozed over.</p>
<blockquote><p>Reverting the Gecko change and pushing for the old Gecko behavior to be standardized. This would re-introduce the problems the change was meant to solve, so I think this isn&#8217;t a real option, either. Furthermore, to get to interop via this path, IE and WebKit would have to change substantially.</p></blockquote>
<p>Because I have always believed that Firefox and Opera were <em>right</em> all along in this behavior, I&#8217;d be far more in support of reverting to the previous way and getting the other browsers to agree to follow suit. All the ugliest part of the hacks in LABjs (the &#8220;text/cache&#8221; junk) is all to deal with how to preload remotely when order isn&#8217;t already enforced. So in my opinion, the direction of Mozilla (and the spec) on this is opposite of the right direction. It may be harder to get the others to agree, but I think it&#8217;s more <em>right</em> than what is happening now.</p>
<blockquote><p>Making Gecko enforce insertion order execution of script-inserted external scripts that don&#8217;t have the async attribute among themselves and standardizing that. This solution looks attractive on surface, but this isn&#8217;t a good solution. A library like LABjs wouldn&#8217;t be able to capability sniff whether scripts will execute in insertion order (even if you tried to load some scripts and saw in-order execution, you couldn&#8217;t be sure it wasn&#8217;t by chance). A solution that relied of UA sniffing wouldn&#8217;t make JS libraries put future IE or WebKit on the new code path when IE or WebKit started enforcing insertion order execution.</p></blockquote>
<p>I agree this isn&#8217;t ideal or a long-term solution, but doing so for now (basically, going back to the way it was) might be a decent solution until we can all have time to figure out the better long term solution that suits everyone.</p>
<blockquote><p>Adding a DOM-only boolean property called &#8220;ordered&#8221; to script element nodes. This property would default to false. JS libraries could capability sniff for the presence of the DOM property to see if it is supported and set it to true to request script-inserted scripts that have the property set to true execute in insertion order among themselves (but not blocking other scripts). If we address your use case at all, this is the best solution I&#8217;ve come up with so far. Note that this would give IE and WebKit a capability-sniffing upgrade path to getting to the code path that doesn&#8217;t require bogus type preload.</p></blockquote>
<p>I recognize this as a possible (and perhaps valid and viable) solution. I think more needs to be discussed on it or other similar approaches. I have some concerns, but nothing that would probably be a deal-breaker on that path.</p>
<blockquote><p>(I realize that it looks offensive to say &#8220;If we address your use case at all&#8221;, but doubting the need to address a use case is a healthy standard operating procedure. After all, so far actual breakage of concrete existing sites hasn&#8217;t been shown.)</p></blockquote>
<p>It&#8217;s fine to doubt and to discuss. It&#8217;s not ok to doubt and <em>not</em> discuss, which is what it felt like was happening before and why I reacted so strongly. If Mozilla will commit to opening up a public forum discussion and helping to get all the other browsers involved in that discussion so we can all agree on something that works for everyone, <strong>that to me is the ideal long-term resolution</strong>.</p>
<p>In the short-term though, we need to figure out what&#8217;s going to happen with FF4 scheduled to release in just a few weeks as I understand it.</p>
<h3>Summary</h3>
<p>I appreciate the Mozilla developer(s) beginning to engage in this discussion. I hope the end result is that a productive dialog can be had with all of us on equal footing and all important use cases addressed. That&#8217;s the only thing I&#8217;m calling for right now. Well, that and &#8220;what do we do about the short-term FF4 change?&#8221; I have an enormous amount of respect for Mozilla, but I hope the same courtesy can be granted of others like me who aren&#8217;t so &#8220;in the loop&#8221; but have valid concerns nonetheless.</p>
<div><a class="addthis_button" href="//addthis.com/bookmark.php?v=250" addthis:url='http://blog.getify.com/mozilla-labjs-part-2/' addthis:title='Mozilla &amp; LABjs&#8230; part 2 '><img src="//cache.addthis.com/cachefly/static/btn/v2/lg-share-en.gif" width="125" height="16" alt="Bookmark and Share" style="border:0"/></a></div>]]></content:encoded>
			<wfw:commentRss>http://blog.getify.com/mozilla-labjs-part-2/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>LABjs: why not just concat?</title>
		<link>http://blog.getify.com/labjs-why-not-just-concat/</link>
		<comments>http://blog.getify.com/labjs-why-not-just-concat/#comments</comments>
		<pubDate>Sat, 28 Nov 2009 05:41:08 +0000</pubDate>
		<dc:creator>getify</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Performance Optimization]]></category>
		<category><![CDATA[UI Architecture]]></category>
		<category><![CDATA[architecture]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[labjs]]></category>
		<category><![CDATA[loading]]></category>
		<category><![CDATA[optimization]]></category>
		<category><![CDATA[page]]></category>
		<category><![CDATA[ui]]></category>

		<guid isPermaLink="false">http://blog.getify.com/?p=97</guid>
		<description><![CDATA[Update [8/12/2010: I've posted a performance benchmark test to try and gather some numbers from the crowd-at-large on how single large concat'd files perform compared to chunking that big file into a couple of smaller files to download in parallel. I encourage you to go right now and click each of the buttons a few [...]]]></description>
			<content:encoded><![CDATA[<h5>Update</h5>
<p>[<strong>8/12/2010:</strong> I've posted a performance benchmark test to try and gather some numbers from the crowd-at-large on how single large concat'd files perform compared to chunking that big file into a couple of smaller files to download in parallel. I encourage you to go right now and click each of the buttons a few times, and then spread the link on to others. <a href="http://test.getify.com/concat-benchmark/test-1.html" target="_blank">Concat Performance Benchmark Test #1</a>]</p>
<p>By far the most prevalent question circulating right now in the wake of <a<br />
href="http://labjs.com">LABjs</a>&#8216; <a href="http://blog.getify.com/2009/11/labjs-new-hotness-for-script-loading/">initial public launch</a> (IPL, I guess!?) is the understandable: &#8220;Why do I need a loader like LABjs for multiple files when I can just concat everything into one file?&#8221;</p>
<p>Fair enough, this is an important question to address. You shouldn&#8217;t just take my implied assumption at face value; we need to dig into this so you understand why I feel so strongly that LABjs offers something better than what you are probably currently doing on your sites.</p>
<p>The short answer is, <strong>BOTH</strong>! You should concat files together when possible, <em>and</em> you should load your file(s) with a loader like LABjs. If you only do one or the other, you have missed out on the bigger picture of page-load optimization.</p>
<h2>YSlow/PageSpeed only value reducing HTTP requests</h2>
<p>Before I get into specifics about why I think LABjs brings something new and beneficial to the table, let&#8217;s tackle what I consider to be an interesting but perhaps misleading &#8220;truth&#8221;. I am firmly in a minority camp in my skepticism that reduction of HTTP requests is <em>the only</em> answer to the question of how to load a site more efficiently &#8212; actually, to be more accurate, how to load a site&#8217;s <em>JavaScript</em> more efficiently.</p>
<p>I bet that you are recalling the YSlow rules and the tried-and-true practice that concat&#8217;ing all your JS files into one file for production is the surest way to speed up your page loads. And you&#8217;re probably doubting my credibility because I would question such a fundamental &#8220;truth&#8221; as HTTP request reduction.</p>
<p>It is true that, especially for the largest sites on the internet (millions of page-views per month and more), the sheer volume of HTTP requests from a typical page profile (dozens of images, multiple style sheets, half a dozen JS files, etc) quickly overloads internet connections, server load-balancers, the user&#8217;s device, and even the browser itself. And anything you can do to reduce that overload will go a long way toward helping the site load with acceptable performance.</p>
<p>Sites like Yahoo and Google have taught us the basic principles of HTTP request reduction as an effective way to cut down on the overall page loading delays. For instance, consider <a href="http://spriteme.com">Spriting to combine images</a>, CSS concatenation, and, yes, JavaScript concatenation. Some sites, like Digg, have even experimented with the extreme &#8212; inlining all page resources, even binary image data, into a single multi-part request! And just recently, we saw a <a href="http://limi.net/articles/resource-packages/">proposal for Resource Packaging</a> as <a href="http://blog.getify.com/2009/11/resource-packaging-silver-bullet/">another way</a> to combine multiple types of data into single responses for HTTP request reduction.</p>
<p>If you run a site that has well over 50 million page views per month (I sure don&#8217;t!), you probably would assert that this is the easiest and <em>most</em> effective page-load optimization. And I&#8217;d be hard-pressed to go up against the brightest and the best at the world&#8217;s largest web properties to suggest that it&#8217;s not true, at least at their page-view volume.</p>
<h2>What&#8217;s true is true. Period.</h2>
<p>Here&#8217;s what I will suggest: maybe, just maybe, what&#8217;s true for Google at a hundred-million page views <em>may not identically and exactly</em> be true for the vast majority of us running sites in the tens-of-thousands page view realm. The &#8220;big boys&#8221; are up in rarefied air, and from there they certainly have the request volume to test, re-test, and &#8220;prove&#8221; these various rules of optimization. But in the same way that water behaves in strange, almost contradictory ways at extremes of hot or cold temperature, maybe the <em>art</em> of optimizing page loads isn&#8217;t as simple as &#8220;1 http request is always better than 2.&#8221;</p>
<p>Even for small sites (like the one you&#8217;re currently reading!), it&#8217;s still vitally important to reduce page load time and optimize for faster page views. So, I&#8217;ll readily and eagerly admit that a <em>key strategy</em> in that effort is for all of us to work to reduce our HTTP request loads.</p>
<h2>OK, so you agree concat&#8217;ing is best?</h2>
<p>Not so fast. Like I said, this issue is more complex than I think most of us are ready to admit. Too easily, we run the YSlow plugin tests on our site, and when we reduce HTTP requests by concat&#8217;ing our JS files, because it tells us to, not only does our perceived page-load times decrease, but our YSlow grade goes up! Success! We&#8217;ve proved the hypothesis, there&#8217;s nothing more to say, right?</p>
<p><strong>I don&#8217;t think this in and of itself means you have achieved the pinnacle of page-load performance, you&#8217;ve simply taken the first of many steps toward nirvana.</strong></p>
<p>In my opinion, loading your JavaScript in an efficient and optimized way cannot be boiled down into a simple set of &#8220;rules&#8221; &#8212; you can take such &#8220;truths&#8221; as good places to start, but you still have to refine the strategies to fit your particular site and audience. Indeed, this will start to look more like an art than a science, if done correctly. </p>
<h2>I&#8217;m not so sure&#8230;</h2>
<p>Maybe by this point, you&#8217;re still not convinced there&#8217;s more to the story, and you&#8217;re probably starting to feel like LABjs doesn&#8217;t really have that much to offer you. </p>
<p>Before you go, let me just say this: even if you <strong>only</strong> ever have one JavaScript file on your site, because concat&#8217;ing is the way to go for you, and you think that by putting a single &lt;script> tag at the bottom of your page, you&#8217;ve achieved the ultimate JavaScript loading solution &#8212; <strong>there is still some benefit to using LABjs to load that one file.</strong></p>
<p>Why? A regular &lt;script> tag in the main HTML, even at the foot of your document, will always block the page&#8217;s loading completion, which means that users will still be &#8220;stuck&#8221; waiting for that file to complete before they can do anything with your page. Now, for some pages, you may really not want the users to do anything until the JavaScript fully processes everything, but most people agree that designing sites for progressive-enhancement is a positive thing.</p>
<p>So, if you can design your sites so that there&#8217;s something meaningful for the users to see or even <em>do</em> while they wait for the JS to kick in, they will probably be happier with your site than if you just make them wait. And that&#8217;s where LABjs comes in. Loading JavaScript dynamically <strong>unblocks</strong> the rest of the page&#8217;s resources (and <a href="http://blog.getify.com/2009/11/why-dom-ready-still-sucks/">DOM-ready</a>!), freeing the user from the iron grip of the hanging &#8220;almost loaded but not yet&#8221; feeling that most sites force upon their users.</p>
<p>Include the small 4k of LABjs (via an <strong>inline</strong> &lt;script> tag) into your page, and use it to load your single JavaScript file, and I believe your users will see an improved, even slightly, user-experience on page-load, as long <a href="http://blog.getify.com/2009/11/labjs-new-hotness-for-script-loading/#ux-labjs">as you&#8217;re careful</a> about it.</p>
<h2>OK, so maybe there is more to this loading thing</h2>
<p>Keep reading if you&#8217;re ready to take the <a href="http://en.wikipedia.org/wiki/Red_pill">Red Pill</a> and dive deeper down the rabbit hole.</p>
<p><strong>(&#8230; more &#8230;)</strong></p>
<div><a class="addthis_button" href="//addthis.com/bookmark.php?v=250" addthis:url='http://blog.getify.com/labjs-why-not-just-concat/' addthis:title='LABjs: why not just concat? '><img src="//cache.addthis.com/cachefly/static/btn/v2/lg-share-en.gif" width="125" height="16" alt="Bookmark and Share" style="border:0"/></a></div>]]></content:encoded>
			<wfw:commentRss>http://blog.getify.com/labjs-why-not-just-concat/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Why DOM-ready still sucks</title>
		<link>http://blog.getify.com/why-dom-ready-still-sucks/</link>
		<comments>http://blog.getify.com/why-dom-ready-still-sucks/#comments</comments>
		<pubDate>Sat, 21 Nov 2009 16:32:44 +0000</pubDate>
		<dc:creator>getify</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[dom-ready]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[loading]]></category>

		<guid isPermaLink="false">http://blog.getify.com/?p=44</guid>
		<description><![CDATA[For those of you who are familiar with JavaScript libraries, you are probably at least a little bit aware that there is an &#8220;event&#8221; that occurs during the loading of a page which abstractly represents the point in time in which the browser has fully processed the structure (aka, the &#8220;DOM&#8221;) of the HTML document [...]]]></description>
			<content:encoded><![CDATA[<p>For those of you who are familiar with JavaScript libraries, you are probably at least a little bit aware that there is an &#8220;event&#8221; that occurs during the loading of a page which abstractly represents the point in time in which the browser has fully processed the <strong>structure</strong> (aka, the &#8220;DOM&#8221;) of the HTML document being displayed. </p>
<p>This &#8220;event&#8221; is separate from (and ostensibly noticeably earlier than) the more familiar &#8220;onload&#8221; event, whose defined behavior means that all of the page&#8217;s initial resources have fully loaded &#8212; <strong>before</strong> &#8220;onload&#8221;, there is an earlier state at which things (such as images and styles) are still loading, but the basic plan or skeleton of the page is now known and understood and the browser knows what to expect.</p>
<p>This &#8220;event&#8221; is, in some browsers, an actual <em>event</em>, in other browsers it&#8217;s a state which can be passively observed, and in some browsers, it has to be divined by examining the alignment of the stars and taking into account the wind speed and gravitational pull of various heavenly bodies, divided by the&#8230;</p>
<p>You get the point, there&#8217;s an &#8220;event&#8221; that the browsers try (and some do better than others at this attempt) to expose for when the DOM is ready, which I will now conveniently and uncreatively call &#8220;DOM-ready&#8221;.</p>
<h2>So what if the DOM is ready or not?</h2>
<p>Let me make sure that you understand the importance of DOM-ready. In some cases, if you have JavaScript logic that tries to modify the DOM of your page <em>before</em> this DOM-ready event has occured/passed, you can wreak havoc with that browser, and in some cases, cause a fatal error and browser crash. </p>
<p>Think of it this way: if i&#8217;m standing on one foot, precariously balanced, and trying to pull on a sock over my bare foot, and my wife comes along and tugs on the rug I&#8217;m standing on, am I likely to get that sock put on successfully? Am I even likely to stay standing? Probably not.</p>
<p>So, it&#8217;s wise to make sure that you don&#8217;t take any actions which could adversely affect the browser&#8217;s ability to get his sock on, at least if you don&#8217;t want him to fall over. And that&#8217;s why we have the concept of DOM-ready &#8212; to make sure that you don&#8217;t manipulate the DOM too early.</p>
<p>Moreover, the major JS frameworks (for that matter, most of even the minor JS tools out there) all provide ways for you queue up code to be executed at some later time, that time being when the framework is able to detect that the event has occured and that it&#8217;s now safe for your code to go about the business of changing things.</p>
<h2>The frameworks all take care of that mess for me, right?</h2>
<p>Ahh, don&#8217;t we wish that were completely true. If it were, this post would be somewhat pointless, and you&#8217;d instead be enjoying eating a pizza or watching re-runs of Grey&#8217;s Anatomy.</p>
<p>Alas, the world is not that simple. There&#8217;s a little known, but I believe important, problem with the way DOM-ready detection is accomplished by the frameworks in a cross-browser way. I&#8217;m not going to bore you with all the details of just how this detection occurs, but let&#8217;s just say it gets a little hackish in some cases.</p>
<p>For the lion-share of use cases, the DOM-ready detection that the current framework versions employ is acceptable, at least for all the browsers that most of us really care about working correctly. If you&#8217;re still worried about Netscape 3.0 though, you&#8217;re on your own&#8230; good luck!</p>
<p>But, a subtle problem creeps in when you step outside the normal set of uses cases &#8212; those being where you simply include a &lt;script> tag at the top (or bottom, if you&#8217;re really clever) of your HTML document that loads your framework of choice (let&#8217;s say &#8220;jquery.js&#8221; for the purposes of this post). </p>
<p>Let&#8217;s say you have a mashup where you are pulling together multiple websites, and maybe <a href="http://jquery.com">jQuery</a> is not guaranteed to already be present on the page. &#8220;No problem!&#8221; you say, because you know how to load a script file on-demand, so you&#8217;ll just fire off a request to do so, and wait for jQuery to be present before you proceed to make calls against it (and, of course, then use it to change the page!)</p>
<p>Or, let&#8217;s say you have a bookmarklet that people can use to popup some nifty little widget in their page of choice, and again, you want to make sure that jQuery is present for your code to utilize. Again, we&#8217;ll just load jQuery on-the-fly, and we should be good to go, right?</p>
<p>Or even better, let&#8217;s just say you&#8217;ve got a really complex application, which loads different scripts into the page at different times depending on the state of what the user does. Yet again, you may need to fetch jQuery at some point well after the initial page loading occured.</p>
<p>There&#8217;s yet another use-case, which is actually the one that I ran into that caused me to discover this issue several months ago. If your page uses a script loader, such as <a href="http://labjs.com">LABjs</a>, the one I wrote in cooperation with <a href="http://stevesouders.com">Steve Souders</a> (of Yahoo! and Google fame), you have to be aware of how certain scripts, notably the frameworks, do their DOM-ready detection and how this applies when the script is loaded dynamically. </p>
<p>Because script-loaders remove the &#8220;blocking&#8221; nature of script loading that normal &lt;script> tags provide, it is actually quite possible to get into a situation where you load a script, like &#8220;jquery.js&#8221;, but the rest of the page is so well optimized that the DOM-ready event passes before jQuery arrives. You may very well not intend this to occur, but it can, and worse yet, it can happen as a race-condition, where it happens sometimes, and not others.</p>
<p><strong>(&#8230; more &#8230;)</strong></p>
<div><a class="addthis_button" href="//addthis.com/bookmark.php?v=250" addthis:url='http://blog.getify.com/why-dom-ready-still-sucks/' addthis:title='Why DOM-ready still sucks '><img src="//cache.addthis.com/cachefly/static/btn/v2/lg-share-en.gif" width="125" height="16" alt="Bookmark and Share" style="border:0"/></a></div>]]></content:encoded>
			<wfw:commentRss>http://blog.getify.com/why-dom-ready-still-sucks/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Loading JavaScript: Even a caveman can do it</title>
		<link>http://blog.getify.com/loading-javascript-even-a-caveman-can-do-it/</link>
		<comments>http://blog.getify.com/loading-javascript-even-a-caveman-can-do-it/#comments</comments>
		<pubDate>Tue, 17 Nov 2009 06:46:44 +0000</pubDate>
		<dc:creator>getify</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Performance Optimization]]></category>
		<category><![CDATA[UI Architecture]]></category>
		<category><![CDATA[architecture]]></category>
		<category><![CDATA[compression]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[loading]]></category>
		<category><![CDATA[minification]]></category>
		<category><![CDATA[optimization]]></category>
		<category><![CDATA[ui]]></category>

		<guid isPermaLink="false">http://blog.getify.com/?p=8</guid>
		<description><![CDATA[I recently gave a talk about JavaScript Loading at JSConf.EU in Berlin. Video/audio of the talk will be made available online eventually, and I will link to it here once that happens. But, in fact, I will be re-presenting this same talk at the November meeting of Austin.Javascript (@AustinJS), on Tues Nov 17th, at 7:30pm. [...]]]></description>
			<content:encoded><![CDATA[<p>I recently gave a <a href="http://www.slideshare.net/shadedecho/loading-javascript-even-a-caveman-can-do-it">talk about JavaScript Loading</a> at <a href="http://jsconf.eu">JSConf.EU</a> in Berlin. Video/audio of the talk will be made available online eventually, and I will link to it here once that happens. But, in fact, I will be re-presenting this same talk at the November meeting of Austin.Javascript (<a href="http://twitter.com/austinjs">@AustinJS</a>), on <a href="http://www.linkedin.com/groupAnswers?viewQuestionAndAnswers=&#038;gid=1913658&#038;discussionID=9818762">Tues Nov 17th, at 7:30pm</a>. Come join us if you can! My hope is to push the envelope of how we all approach loading JavaScript resources into our pages.</p>
<p>The talk covers a number of different strategies, each of which I will be covering in subsequent posts here. But I wanted to give a quick overview of what you can expect:</p>
<ol>
<li><strong>Build-time optimization:</strong> it&#8217;s important to utilize build-process optimizations to manage local scripts and dependency chains. Depending on your server architecture and frameworks, there are lots of different choices that you have here, but the key is have a system that can manage this intelligence for you, freeing you and the other developers on your team from having to maintain the techniques yourselves.</li>
<li><strong>Load/run-time profiling:</strong> We&#8217;ve all heard the advice that the best way to get JavaScript resources onto the page is to only have one JavaScript file, meaning we should always concat all our individual files into one massive output file as it goes to the browser in production. But does this always make sense? I believe it only rarely does.
<p>There are a number of tools for profiling your site/application at load-time and at run-time, to decide what parts of your JavaScript are critical to load at the beginning, and what parts can be safely deferred until later and be lazy-loaded. Doing so not only speeds up the load time user-experience of your site/application, but it also often helps create better long(er)-term user-experience by more effectively utilizing the user&#8217;s browser cache. You can profile manually, or automatically, but you shouldn&#8217;t ever put a site or application into production without at least examining these strategies and trying a few different options.</li>
<li><strong>Post-optimize your minified JavaScript:</strong> For a long time, it felt like the book was closed on minification/obfuscation. There&#8217;s only so much white-space you can remove from a JavaScript file, and only so many variable names you can shorten, before a script seems as small as it&#8217;s going to get. But, it would seem there are more chapters to be written, yet.
<p>Recent releases of projects like Google Closure prove that there&#8217;s a lot more ground to cover on what we can do to optimize and shorten our scripts. I also have a project called <a href="http://mincir.it">Mincir</a> which is aimed at specifically running post-minification optimization steps on files to squeeze out more bytes. Smaller files means quicker loading and better user-experience. And that means happier users and happier developers.</li>
<li><strong>Dynamic, on-demand, parallel loading of JavaScript:</strong> While the landscape of how the browsers handle the &lt;script> tag is quite diverse and often ugly, there are ways to normalize this behavior cross-browser, and in the process allow all your JavaScript resources to load at the same time, in parallel with each other and the rest of the page assets. This is actually not that hard. But ensuring proper execution order, not only of loaded scripts, but also of coupled inline script executions, is where the magic happens.
<p>Luckily, a project of mine, called <a href="http://labjs.com">LABjs</a>, does just such a thing. It&#8217;s a general purpose, flexible, and capable JavaScript loader, that allows you to load just about any script or group of scripts onto any page, at any time.</li>
<li><strong>Load and cache &#8220;not-code&#8221;, execute &#8220;code&#8221; later:</strong> Sometimes, the best way to get JavaScript onto the page is not to load JavaScript at all. This may seem like a crazy statement, but you actually have some options as to how your &#8220;code&#8221; gets delivered to the page. For instance, you can transfer the code inside a multi-line comment block, or even as an escaped string literal assigned to a JavaScript variable. You may ask, why would I do such a crazy thing? Well, it turns out that there&#8217;s a significant amount of time spent processing JavaScript once it&#8217;s loaded onto a page.
<p>So, if on one page you want to &#8220;preload&#8221; a script into the cache for use on a subsequent page, like you have done with images for years, you pay a penalty for that script simply being added to your page. Unless of course it&#8217;s not really a script at that point. If it&#8217;s a comment or a string literal, then it is loaded and saved into the browser cache, but there&#8217;s almost no processing time on the page at that point. Later, on another page, you can recall this &#8220;not-code&#8221; from cache, and transform it into executable code. </p>
<p>This type of technique is quite valid for desktop browsers, but is particularly helpful for mobile browsers where the biggest bottleneck is not actually usually the  connection speed but the processing power of the mobile device in handling large amounts of not-used-yet code while rendering a page.</li>
</ol>
<p>None of these techniques are in and of themselves a complete solution to this issue, nor are these ideas the final word on the topic. But it&#8217;s time we evolve how we load our JavaScript onto pages and move beyond the 1990&#8242;s version of the plain ol&#8217; &lt;script> tag. I hope this talk and these posts will get that ball rolling.</p>
</p>
<div style="width:425px;text-align:left" id="__ss_2452641">
<div><a href="http://www.slideshare.net/shadedecho/loading-javascript-even-a-caveman-can-do-it" title="Loading JavaScript: Even a caveman can do it">Loading JavaScript: Even a caveman can do it</a></div>
</p>
<p><object style="margin:0px" width="425" height="355"><param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=caveman-091108165033-phpapp02&#038;stripped_title=loading-javascript-even-a-caveman-can-do-it" /><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><param name="wmode" value="opaque"/><embed src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=caveman-091108165033-phpapp02&#038;stripped_title=loading-javascript-even-a-caveman-can-do-it" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355" wmode="opaque"></embed></object>
<div style="font-size:11px;font-family:tahoma,arial;height:26px;padding-top:2px;">View more <a style="text-decoration:underline;" href="http://www.slideshare.net/">presentations</a> from <a style="text-decoration:underline;" href="http://www.slideshare.net/shadedecho">Kyle Simpson</a>.</div>
</div>
<div><a class="addthis_button" href="//addthis.com/bookmark.php?v=250" addthis:url='http://blog.getify.com/loading-javascript-even-a-caveman-can-do-it/' addthis:title='Loading JavaScript: Even a caveman can do it '><img src="//cache.addthis.com/cachefly/static/btn/v2/lg-share-en.gif" width="125" height="16" alt="Bookmark and Share" style="border:0"/></a></div>]]></content:encoded>
			<wfw:commentRss>http://blog.getify.com/loading-javascript-even-a-caveman-can-do-it/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Content Delivery Network via getiblog.2static.it

Served from: blog.getify.com @ 2012-05-18 09:44:35 -->
