<?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; labjs</title>
	<atom:link href="http://blog.getify.com/tag/labjs/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.getify.com</link>
	<description>open-source, performance, javascript &#38; ui musings</description>
	<lastBuildDate>Mon, 23 Aug 2010 20:50:24 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Simulated Chaining in JavaScript</title>
		<link>http://blog.getify.com/2010/02/simulated-chaining-in-javascript/</link>
		<comments>http://blog.getify.com/2010/02/simulated-chaining-in-javascript/#comments</comments>
		<pubDate>Wed, 10 Feb 2010 16:18:04 +0000</pubDate>
		<dc:creator>getify</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[chaining]]></category>
		<category><![CDATA[functions]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[labjs]]></category>

		<guid isPermaLink="false">http://blog.getify.com/?p=213</guid>
		<description><![CDATA[What I have to talk about here is not going to be earth shattering, but it is a technique that has proved useful in a few different sites and scenarios for me. In fact, I regularly get questions regarding advanced use cases for LABjs (a parallel JavaScript loader), and invariably it comes back to something [...]]]></description>
			<content:encoded><![CDATA[<p>What I have to talk about here is not going to be earth shattering, but it is a technique that has proved useful in a few different sites and scenarios for me. In fact, I regularly get questions regarding advanced use cases for <a href="http://labjs.com">LABjs</a> (a parallel JavaScript loader), and invariably it comes back to something along these lines.</p>
<p>If you already understand object/function call chaining, just <a href="#goodstuff">skip down to the good stuff</a>.</p>
<h2>The chains that bind you</h2>
<p>Just so we&#8217;re all on the same page, &#8220;chaining&#8221; is this wonderful functional property of languages like JavaScript (which treat a function as a first-class citizen). It essentially amounts to making a function call, and the return value from the function is itself either another callable function, or more often, an object that has functions which are directly callable.</p>
<p><a href="http://jquery.com">jQuery</a> is probably the most prevalent use of this concept. Some example jQuery code:</p>
<pre style="background-color:#ddd;">
$("p.neat").<strong>addClass</strong>("ohmy").<strong>show</strong>("slow");
</pre>
<p>In this snippet, <span style="background-color:#ddd;">$(&#8230;)</span> is actually a function call, just like <span style="background-color:#ddd;">foo(&#8230;)</span> or <span style="background-color:#ddd;">doSomethingReallyEvilButDontTellAnyone(&#8230;)</span> (just kidding; only Google would name a function something crazy like that).</p>
<p>The return value from the <span style="background-color:#ddd;">$(&#8230;)</span> call is an object, that has a bunch of properties on it, many of whom are functions. Consider that conceptually an object is returned like this (not actual code):</p>
<pre style="background-color:#ddd;">
function $(...) {
   // do something cool
   return {
      addClass:function(...){...},
      show:function(...){...},
      ...
   };
}
</pre>
<p>So, what happens is that when that object is returned from the function, JavaScript will allow you to immediately <em>de-reference</em> the return value (the object), and using &#8220;.&#8221; (dot notation), access its properties. So <span style="background-color:#ddd;">$(&#8230;).<strong>addClass(&#8230;)</strong></span> makes the first chained call (&#8220;addClass&#8221;) off the return value from <span style="background-color:#ddd;">$(&#8230;)</span>. Then, <span style="background-color:#ddd;">addClass(&#8230;)</span> also returns the same (same kind, not identical) object, and so this second return value can identically be de-referenced and a chained function be called. I like to refer to each chained function call as a &#8220;chain link&#8221;.</p>
<p>This chaining can theoretically go on forever (although for code readability it can be argued that 3 or 4 chain links is probably the most you want to practically do in production code, exceptions aside).</p>
<h2>Why chains?</h2>
<p>Probably the single biggest argument for developing code API&#8217;s that are of this chaining style is to pass context along from one function call to another in an automatic and graceful feeling way. For instance, in jQuery&#8217;s case, the reason for chaining is that internally, there&#8217;s a collection (a fancy array) of objects, and as each chained function is called, internally it loops over the collection of objects and performs tasks (such as expanding/contracting the collection, modifying objects in the collection, etc).</p>
<p>jQuery could work functionally this way and achieve the same effect:</p>
<pre style="background-color:#ddd;">
var collection = $("p.neat");
$.addClass(collection,"ohmy");
$.show(collection,"slow");
</pre>
<p>See how we had to pass in the &#8220;collection&#8221; object/array for every function call? It works, but that code is arguably a little less graceful. And certainly it&#8217;s a little more repetitive.</p>
<p>So, chaining was a way to accomplish the same task (context passing across function calls) but in a prettier, more graceful fashion. Generally, the idea of adjusting the way a set of code works to make it more expressive or pleasant is called adding &#8220;syntactic sugar&#8221;.</p>
<p>To be fair, syntactic sugar is not the only reason why chaining in functional languages is useful. In fact, with LABjs, which also has a similar type of chaining API (although internally operates quite differently from jQuery), the reasons were only partially &#8220;sugar&#8221;; chaining in LABjs&#8217; case actually provides an effective solution to guard against certain types of race conditions. </p>
<p>Because of how JavaScript (single-threaded) works, a chain of function calls is more or less guaranteed to complete fully before any other code comes in and interrupts to execute. This is also <em>probably</em> true of a series of distinct function calls in a single code block, but even more definitely so for a chain of function calls or (as we&#8217;ll see in a moment), a loop of function calls.</p>
<h2>So why not a chain?</h2>
<p>Since chains are powerful and also tend to lead to more expressive code (unless abused) and also generally <em>less code</em>, you may wonder, why wouldn&#8217;t we always use chains for everything?</p>
<p>The obvious: some function calls are, by their nature, independent and thus do not need to (or should not!) share a context. Also, under certain circumstances, chaining can be less efficient internally, depending on how the context is stored/shared/used.</p>
<p>Let&#8217;s face it: if you really want to write your entire &#8220;program&#8221; on one line with a bunch of obscure/abusive syntactical tricks, just go write some Perl. I kid, I kid.</p>
<p>But beyond those things, one fundamental fact of chaining is that it&#8217;s not &#8220;dynamic&#8221;. Basically, what I mean by this is that you pretty much hard-code at the time of code writing (aka, &#8220;build time&#8221;) how a chain is constructed. You can&#8217;t decide at run time based on environmental conditions that some parts of the chain are conditionally not executed (like by wrapping them in an if-statement, etc). </p>
<p>The ability to do that kind of run-time logic is restricted syntactically to individual statements/function calls, so a chain will be considered an atomic single indivisible unit for those purposes. You could conditionally decide whether to run one of several different chains depending on conditions, but each chain to be chosen would be pre-defined and for the most part immutable.</p>
<p>So, the truth is, chaining provides a syntactically prettier (more expressive) code approach, but it limits us a little bit in terms of coding flexibility.</p>
<h2>I need more concrete</h2>
<p>To illustrate, let&#8217;s revisit jQuery&#8217;s example code from above. Let&#8217;s say instead that what you really want to do is only run the <span style="background-color:#ddd;">addClass(&#8230;)</span> call if some condition is true (like for instance, the user has a valid login session, or whatever). So, you want to basically do conceptually something like this:</p>
<pre style="background-color:#ddd;">
$("p.neat")
<strong>if (userLoggedIn()) {</strong>  .addClass("ohmy")  <strong>}</strong>  // invalid syntax; will not work!
.show("slow");
</pre>
<p>As I mentioned, you could just have two different chains, one with <span style="background-color:#ddd;">addClass(&#8230;)</span> in the chain, one without it, and choose which chain to execute with your if-statement. This leads to more and repetitive code; a bad thing. DRY (don&#8217;t repeat yourself).</p>
<p>And to be honest, you could also model this in a pure jQuery way (only in the chain using various filters), a variety of different ways. For instance, something like this (while ugly) might work:</p>
<pre style="background-color:#ddd;">
$("p.neat")
.filter(function(){
   return isLoggedIn();
})
.addClass("ohmy")
.end() // ends the most recent filtering operation
.show("slow");
</pre>
<p>What I did here was use <span style="background-color:#ddd;">filter(&#8230;)</span> to basically conditionally empty out the internal collection if not logged in (by returning false for all iterations), meaning the <span style="background-color:#ddd;">addClass(&#8230;)</span> call is essentially ignored, and then revert back to my original collection with a <span style="background-color:#ddd;">.end()</span> call before lastly calling <span style="background-color:#ddd;">.show(&#8230;)</span>.</p>
<p>Let me be clear: while you <em>can</em> do it this way, this is by far not the most efficient or code-friendly way to do so. This would be an example of an anti-pattern, where you are abusing jQuery&#8217;s syntax to solve a problem in a way that it should not be solved. It goes contrary to the spirit of jQuery (&#8220;write less, do more&#8221;).</p>
<h2>Other examples?</h2>
<p>Conditional inclusion of &#8220;chain links&#8221; is only one scenario where traditional chaining is kind of limiting. What if you want to be able to piece together different parts of a chain from various different snippets of code across mutliple functions? This may sound strange, but with complex Web 2.0 web applications, this kind of thing is not uncommon. And it flys in the face of the simple syntactic sugar that chaining is supposed to give us.</p>
<p>Nor are these problems limited to jQuery. With LABjs for instance, a chain might look like this:</p>
<pre style="background-color:#ddd;">
$LAB
.script("framework.js")
.script("loggedin.js")
.wait(function(){
  // do something
});
</pre>
<p>Notice there I may want to <em>only</em> load &#8220;loggedin.js&#8221; if the user is, in fact, logged in. Same syntactic problem as above. But LABjs has no conditional &#8220;filters&#8221; that can modify the chain&#8217;s context, so we have less options (which in this case is a good thing!)</p>
<p>Or, what if I have a CMS system (like Wordpress for instance) that, across various functions, files, templates, etc, needs to load up a variety of different files, all based on various different environmental conditions and which templates are active, etc. Could I do individual $LAB chain calls in each location? Yes. But then I lose the ability to sequence the loads (ensure execution order). Also, it&#8217;s less memory efficient to do 8 different chains with 1 script in each, as opposed to one chain with 8 scripts in it.</p>
<p>Or, what if I want to use LABjs in a larger solution for <a href="http://happyworm.com/blog/2010/01/28/a-simple-and-robust-cdn-failover-for-jquery-14-in-one-line/">creating robust fallback for resource loading from CDN locations</a>? I need to conditionally decide during loading/run-time if I need to add more scripts to the &#8220;queue&#8221; because one load failed. Not possible with traditional chaining.<br />
<a name="goodstuff"></a></p>
<h2>Unravel the ball of yarn</h2>
<p>All this leads up to say that chaining is great and expressive and powerful, but it&#8217;s not complete for all our needs. So, we need to get a little more creative in those cases. And this technique is what I&#8217;m going to call &#8220;Simulated Chaining&#8221;.</p>
<p>Recall that at the top of this post, we talked about how chaining works because the <em><strong>return value</strong></em> from a function is either a function itself (and thus can be called directly), or it can be an object that can be de-refenenced and has properties which are functions to be executed.</p>
<p>So, our solution lies in that sentence (emphasis added). The <em><strong>return value</strong></em> from a function can either be used immediately, or it can be stored and used later. This isn&#8217;t anything new; if you&#8217;ve ever called any function in any language, you know it can return a value that you can store in a variable. What might have escaped you until now is that this return value that you store can be a contextually sensitive object that would otherwise have been used immediately in a chaining situation. And the cool part is it can be used later (like the next loop iteration) to pick up where the chain left off.</p>
<p>So, instead of pre-defining a chain in our code/build-time, we can instead programatically (at run-time) build up a &#8220;list&#8221; (an array/queue for instance) of functions to be called, and then &#8220;simulate&#8221; a chain by looping through the list, calling each function, and storing the return value for use in the next iteration.</p>
<p>For instance, the LABjs script code above can be done like this instead:</p>
<pre style="background-color:#ddd;">
var queue = []; // empty array for now
...
queue[queue.length] = "framework.js";
...
if (isLoggedIn()) { queue[queue.length] = "loggedin.js";
...
var $L = $LAB;
for (var i=0, len=queue.length; i&lt;len; i++) {
   $L = $L.script(queue[i]);
}
$L.wait(function(){
   // do something
});
</pre>
<p>I <em>simulated</em> a chain of function calls with an iterative for-loop. (NOTE: this is conceptually very similar to how you might take what would otherwise be a recursive set of function calls and turn it into a non-recrusive, iterative loop instead, like for performance reasons). The key is: store the return value from a function call, and then use that stored value as the object that makes the next call. Plain and simple. And now more powerful as you can build up your chains at run-time in as complex a way as is necessary.</p>
<p>Theoretically, a very similar approach could be taken for the jQuery examples above. However, I&#8217;ll leave that as an exercise for the reader.</p>
<p>Let&#8217;s look at one last slightly more advanced example of how to use simulated chaining with LABjs (which is nearly identical to how I do it on several of my sites):</p>
<pre style="background-color:#ddd;">
var queue = [];
...
if (conditionOne()) {
   queue.push("framework.js",false); // false will create an empty .wait()
}
...
if (conditionTwo()) {
   queue.push("plugin1.js","plugin2.js",function(){
      // initialize plugins
   });
}
...
queue.push("mypage.js");
...
var $L = $LAB;
for (var i=0, len=queue.length; i&lt;len; i++) {
   if (typeof queue[i] === "function") $L = $L.wait(queue[i]);
   else if (queue[i] === false) $L = $L.wait();
   else $L = $L.script(queue[i]);
}
</pre>
<p>I specify a queue array that can have one of three types of entries: a [string] is interpreted as a script to load, a [false] is interpreted as an empty .wait() call, and a [function] is passed to a .wait(&#8230;) call. I can use any manner of complex logic to build up the queue, and then in one for-loop at the bottom of the page, simulate the chain by looping over the queue.</p>
<p>Hopefully this helps clear up some of the mysticism that is chaining and give you some other ways to approach the challenging use cases you may face in your code. Go forth and chain (or loop)!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.getify.com/2010/02/simulated-chaining-in-javascript/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>A visual of page-load improvements (via LABjs)</title>
		<link>http://blog.getify.com/2009/12/a-visual-of-page-load-improvements-via-labjs/</link>
		<comments>http://blog.getify.com/2009/12/a-visual-of-page-load-improvements-via-labjs/#comments</comments>
		<pubDate>Thu, 03 Dec 2009 07:21:23 +0000</pubDate>
		<dc:creator>getify</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[UI Architecture]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[labjs]]></category>
		<category><![CDATA[optimization]]></category>
		<category><![CDATA[page load]]></category>
		<category><![CDATA[ui]]></category>

		<guid isPermaLink="false">http://blog.getify.com/?p=156</guid>
		<description><![CDATA[If you run a website but you&#8217;re not aware of Google&#8217;s free Webmaster Tools, you need to get in the loop! These tools allow you to analyze a number of important aspects of how your site is viewed/analyzed by Google&#8217;s search engine index. 
Yet, with all the power and insight these tools give, it still [...]]]></description>
			<content:encoded><![CDATA[<p>If you run a website but you&#8217;re not aware of Google&#8217;s free <a href="https://www.google.com/webmasters/tools/">Webmaster Tools</a>, you need to get in the loop! These tools allow you to analyze a number of important aspects of how your site is viewed/analyzed by Google&#8217;s search engine index. </p>
<p>Yet, with all the power and insight these tools give, it still feels like it&#8217;s best-kept-secret kind of thing that such tools even exist. I never hear anyone talking or writing about them. But I fire them up probably at least once a month to keep an eye on my various sites.</p>
<p>But the hush-hush of Google&#8217;s toolset makes it more exciting to highlight a really cool addition announced today, the <a href="http://googlewebmastercentral.blogspot.com/2009/12/how-fast-is-your-site.html">new Site Performance tool</a>. True, it&#8217;s still in development and very early on, but it already is showing the promise to give great new insights into how your site is performing out in the wild.</p>
<p>We all got the hint a few weeks ago that <a href="http://searchengineland.com/site-speed-googles-next-ranking-factor-29793">Google is planning</a> to <a href="http://www.downloadsquad.com/2009/11/14/google-to-use-page-load-speed-as-a-search-result-ranking-factor/">start considering page-load speed in its indexing algorithm</a>. It would seem to be somewhat &#8220;evil&#8221; for the world&#8217;s largest search engine to start holding page-load speed against everyone&#8217;s sites without being part of the solution. So it shouldn&#8217;t be a surprise that the G would begin releasing various &#8220;tools&#8221; to help the rest of us actually make our sites load faster. </p>
<h2>Bye, bye, birdie!</h2>
<p>Yesterday, the Google Analytics team released a long-overdue update to their suggested snippet for including &#8220;ga.js&#8221; in pages. They wisely ditched the horrid &#8220;document.write()&#8221; approach that has been the standard for the longest time, in favor of this new <a href="http://googlecode.blogspot.com/2009/12/google-analytics-launches-asynchronous.html">asynchronous loading</a> technique. The reason? Quite obviously, this now will <strong>unblock</strong> the loading of GA from page loads, thus preventing Google from being at fault for slower load times!</p>
<p><strong>Side Note:</strong> the suggested code that Google has released has been shown not to be safe with all page structures in some browsers, including (ironically!) Chrome, and Opera. The problem is a faulty assumption that &#8220;document.documentElement.firstChild&#8221; will always return a reference to the HEAD element to append the &lt;script> to. As this <a href="http://yura.thinkweb2.com/jstests/document_head_test_by_Garrett.html">documentElement.childNodes test page</a> from <a href="http://twitter.com/kangax">@kangax</a> shows (if loading in Chrome or Opera, for instance), it&#8217;s (too) easy to accidentally create your page in such a way that this assumption will fail. So, be careful before you jump to switching to Google&#8217;s new snippet. (hint: use LABjs instead. Simpler, easier, and much more reliable!)</p>
<p>But, snarkiness aside, the new &#8220;Site Performance&#8221; tool proves its worth when it shows you a graph of your page&#8217;s estimated average load speeds over the last several months, along with a few basic statistics. It also incorporates a number of Google&#8217;s PageSpeed rules and suggestions for how to reduce factors that are slowing down your page loads.</p>
<p>This information is a really great place to start when trying to attack the performance issues your site may have. In fact, it may help you identify issues you didn&#8217;t even know existed!</p>
<h2>Where&#8217;s the visuals?</h2>
<p>Imagine my elation when I pulled up one of my larger, more traffic&#8217;d sites in the tool and saw this graph:</p>
<div id="attachment_157" class="wp-caption aligncenter" style="width: 557px"><img src="http://getiblog.2static.it/wp-content/uploads/2009/12/site-speed.png" alt="Site page-load performance improvements over last few months" title="site-speed" width="547" height="150" class="size-full wp-image-157" /><p class="wp-caption-text">Site page-load performance improvements over last few months</p></div>
<p>I went from an average of over 3.5 seconds per page load back in August down to a current average of less than 0.3 seconds, which the tool claims is better than 98% of sites! Oh, and btw, this site loads over 105k of JS, images, and CSS, so this isn&#8217;t some puny text-only site getting that kind of loading speed. It&#8217;s a testament to the results you can get if you start caring about page-load optimization on many fronts.</p>
<p>But you know the biggest and most obvious change I made back in July and August on the site in question? That&#8217;s right, you guessed it &#8212; that&#8217;s when I first installed early versions of <a href="http://labjs.com">LABjs</a> for all the site&#8217;s scripts. And over time, I&#8217;ve not only improved the efficiency and capabilities of LABjs, but I&#8217;ve also refined more and more how I work to address page load speeds. To be fair, optimizing script loading was only one of many strategies I used, including <a href="http://spriteme.com">CSS spriting</a> and combining/concat&#8217;ing of JS files to reduce the number of HTTP requests.</p>
<p><strong>But it&#8217;s plainly evident that LABjs was a critical part of this process!</strong></p>
<p>No matter what you feel about dynamic script loaders and if they are useful or not, it&#8217;s clear that all of us have to get more serious about improving our page-load performances if we don&#8217;t want to get left in the Google-index dust. I just believe that script loading is an easy and hugely impactful place to start that process. Remember: optimize, optimize, optimize.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.getify.com/2009/12/a-visual-of-page-load-improvements-via-labjs/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How LABjs speeds up DOM-ready</title>
		<link>http://blog.getify.com/2009/12/how-labjs-speeds-up-dom-ready/</link>
		<comments>http://blog.getify.com/2009/12/how-labjs-speeds-up-dom-ready/#comments</comments>
		<pubDate>Tue, 01 Dec 2009 07:50:21 +0000</pubDate>
		<dc:creator>getify</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[UI Architecture]]></category>
		<category><![CDATA[architecture]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[labjs]]></category>
		<category><![CDATA[ui]]></category>

		<guid isPermaLink="false">http://blog.getify.com/?p=145</guid>
		<description><![CDATA[Last week, I asserted that DOM-ready detection sucks because there&#8217;s a chicken-and-the-egg problem where some frameworks (like jQuery 1.3.2 and before) that do DOM-ready detection have trouble detecting the &#8220;event&#8221; if the framework is loaded dynamically after DOM-ready has already occurred.
I stand by that assertion, especially now that you&#8217;ve seen the launch of LABjs 1.0, [...]]]></description>
			<content:encoded><![CDATA[<p>Last week, I asserted that <a href="http://blog.getify.com/2009/11/why-dom-ready-still-sucks/">DOM-ready detection sucks</a> because there&#8217;s a chicken-and-the-egg problem where some frameworks (like jQuery 1.3.2 and before) that do DOM-ready detection have trouble detecting the &#8220;event&#8221; if the framework is loaded dynamically after DOM-ready has already occurred.</p>
<p>I stand by that assertion, especially now that you&#8217;ve seen the <a href="http://blog.getify.com/2009/11/labjs-new-hotness-for-script-loading/">launch of LABjs 1.0</a>, which unfortunately exposes this shortcoming. </p>
<p>The problem is that <a href="http://labjs.com">LABjs</a>, like many loaders that perform similarly, causes script loading, normally a blocking behavior via &lt;script> tags, to become <strong>unblocked</strong> and asynchronous to the rest of the page. This means that the page&#8217;s DOM-ready will happen before the framework arrives, meaning the DOM-ready detection is vulnerable to &#8220;missing&#8221; the fact that the event has passed.</p>
<p><strong>This still sucks.</strong> We need better solutions for DOM-ready than the hacks we currently use. I mean, come on, IE&#8230; really? We have to <a href="http://javascript.nwbox.com/IEContentLoaded/">loop and test (try/catch) on &#8220;doScroll()&#8221;</a>? Seriously, there has to be a better way! We also need Firefox to release patches to the entire 3.x branch of browsers (and maybe even 2.x!) to support the &#8220;document.readyState&#8221; property, not just 3.6, because it&#8217;s an effective workaround method for detecting if the event has already occurred.</p>
<p>Yeah, but my complaining is not covering any new ground. I do hope browsers start to get the message, though.</p>
<h2>A silver lining in the gray cloud</h2>
<p>There&#8217;s another side to the story &#8212; a different perspective we can take on the effects that LABjs (and other loaders) have on a page&#8217;s DOM-ready.</p>
<p>Let&#8217;s recall and take a deeper look at the 3 waterfall diagrams from <a href="http://blog.getify.com/2009/11/labjs-new-hotness-for-script-loading/">the LABjs launch announcement</a>. As that post points out, FF3 (and other older gen browsers) load &lt;script> tags serially, while newer gen browsers (FF3.5, IE8, Chrome 2+, etc) got smarter and started loading scripts in parallel. But, they <strong>still</strong> block the rest of the page&#8217;s resources, which is a primary reason LABjs steps in with something to offer.</p>
<p>Those diagrams reveal a telling story about DOM-ready you may not have noticed at first (I didn&#8217;t!). Firebug renders a blue line at the point in the timeline where DOM-ready occurs (and a red line for the window &#8220;onload&#8221; &#8212; when all initial resources finish downloading). Notice how the blue line changes in the three diagrams.</p>
<div id="attachment_146" class="wp-caption aligncenter" style="width: 660px"><img src="http://getiblog.2static.it/wp-content/uploads/2009/12/labjs_domready.png" alt="LABjs and DOM-ready" title="labjs_domready" width="650" height="361" class="size-full wp-image-146" /><p class="wp-caption-text">LABjs and DOM-ready</p></div>
<p>That&#8217;s right&#8230; using LABjs on the page sped up the occurence of DOM-ready from ~10.2 seconds in FF3.0 (or ~6 seconds in FF3.5) all the way down to about <strong>0.4 seconds with LABjs!</strong> That is a <strong>major, huge, incredible improvement</strong> no matter how you look at it!</p>
<p>DOM-ready is the time at which the browser typically first renders the content it has available (including styles), and allows the user some sort of basic interaction (scrolling, etc) with the page. And depending on the design of your page, it may be fully functional at DOM-ready, with only non-major decorative changes as the rest of the content arrives. This means that users see and interact with your page, on average, much, <strong>MUCH</strong> sooner than with regular &lt;script> tag usage.</p>
<p>This is a great win for user-experience and page-load performance. Of course, you have to be careful about how this user-experience affects your users, because there can potentially be <a href="http://blog.getify.com/2009/11/labjs-new-hotness-for-script-loading/#ux-labjs">some negative side-effects of these optimizations</a>. </p>
<p>Luckily, as mentioned in that post, there are, I believe, effective ways to deal with the FUBC (flash of un-behaviored content) issue. Moreover, you can (and should!) also think about such things from day 1 when initially designing the UX of your site, for better, more complete patterns of progressive-enhancement.</p>
<h2>I see the light!</h2>
<p>You see, the same thing that is an annoying <em>curse</em> to developers (hampering frameworks&#8217; detection of DOM-ready and thus complicating our script logic) is a <strong>big blessing</strong> to the user. </p>
<p>And in the end, isn&#8217;t that what all of us really care most about: making our sites treat the users to a better experience? Don&#8217;t we owe it to the the general web public to take a little extra effort to generate potentially huge improvements in how users experience our site when they come to visit?</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.getify.com/2009/12/how-labjs-speeds-up-dom-ready/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>LABjs: how to deal with inline code</title>
		<link>http://blog.getify.com/2009/11/labjs-how-to-deal-with-inline-code/</link>
		<comments>http://blog.getify.com/2009/11/labjs-how-to-deal-with-inline-code/#comments</comments>
		<pubDate>Sun, 29 Nov 2009 05:11:30 +0000</pubDate>
		<dc:creator>getify</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[labjs]]></category>

		<guid isPermaLink="false">http://blog.getify.com/?p=122</guid>
		<description><![CDATA[This is a quickie how-to post to help address a couple little gotchas you may run into when implementing LABjs onto your site.
Consider standard page code like this:

&#60;script src="framework.js">&#60;/script>
&#60;script src="myscript.js">&#60;/script>
&#60;script>
  myscript.init();
&#60;/script>
&#60;script>
  framework.init();
  framework.doSomething();
&#60;/script>

In this example, &#8220;myscript.init&#8221; is a function that is defined in &#8220;myscript.js&#8221;, and &#8220;framework.init&#8221; and &#8220;framework.doSomething&#8221; are both defined inside [...]]]></description>
			<content:encoded><![CDATA[<p>This is a quickie how-to post to help address a couple little gotchas you may run into when implementing <a href="http://labjs.com">LABjs</a> onto your site.</p>
<p>Consider standard page code like this:</p>
<pre style="background-color:#ddd;">
&lt;script src="framework.js">&lt;/script>
&lt;script src="myscript.js">&lt;/script>
&lt;script>
  myscript.init();
&lt;/script>
&lt;script>
  framework.init();
  framework.doSomething();
&lt;/script>
</pre>
<p>In this example, &#8220;myscript.init&#8221; is a function that is defined in &#8220;myscript.js&#8221;, and &#8220;framework.init&#8221; and &#8220;framework.doSomething&#8221; are both defined inside of &#8220;framework.js&#8221;.</p>
<p>The first pass at implementing LABjs to load these scripts may seem like this code would work correctly:</p>
<pre style="background-color:#ddd;">
&lt;script>
  $LAB
  .script("framework.js")
  .script("myscript.js")
<strong>  .wait(myscript.init);</strong>  // won't work!
&lt;/script>
&lt;script>
  framework.init();  // also won't work
  framework.doSomething();  // also won't work
&lt;/script>
</pre>
<h2>Why is my function reference undefined?</h2>
<p>Firstly, the code &#8220;.wait(myscript.init)&#8221; seems like this is the correct way to tell LABjs to run &#8220;myscript.init&#8221; function after the scripts finish loading. But there&#8217;s a subtle problem: with regular &lt;script> tags, the inline script block in the first snippet that has &#8220;myscript.init()&#8221; in it is guaranteed to not even be EVALUATED before the scripts synchronously have loaded before it. So, &#8220;myscript.init&#8221; is guaranteed to have been defined by that point, so it will work as expected.</p>
<p>But, in the second snippet, we pass a reference to &#8220;myscript.init&#8221; into the wait() function. But, &#8220;myscript.init&#8221; hasn&#8217;t been defined yet, because the chain for LABjs will execute immediately, as it starting to load the scripts. This means that at the time that .wait(&#8230;) first gets parsed, &#8220;myscript.init&#8221; doesn&#8217;t exist. It will be defined, later, when the scripts finish, but the reference is undefined at that point, and thus cannot be used yet.</p>
<p>So, the simple way to fix this problem is this:</p>
<pre style="background-color:#ddd;">
&lt;script>
  $LAB
  .script("framework.js")
  .script("myscript.js")
  .wait(<strong>function(){</strong> myscript.init<strong>(); }</strong>);
&lt;/script>
&lt;script>
  framework.init();
  framework.doSomething();
&lt;/script>
</pre>
<p>So, what we pass to &#8220;wait&#8221; is not a reference to the as-of-yet-undefined &#8220;myscript.init&#8221;, but an anoynmous function that will call/execute &#8220;myscript.init()&#8221; at the proper time. Because of how functions and closures and execution bindings work in JavaScript, this syntax will wait to try to resolve/execute &#8220;myscript.init()&#8221; until that function is guaranteed to have been loaded (because &#8220;myscript.js&#8221; finished loading!).</p>
<p>It&#8217;s a simple but devious concept in JavaScript&#8230; the difference between a function reference &#8220;myscript.init&#8221; and an anonymous function that will call the intended function later &#8220;function(){myscript.init();}&#8221;.</p>
<h2>OK, but I still have undefined code</h2>
<p>For the exact same reason that &#8220;myscript.init&#8221; wasn&#8217;t yet defined when we tried to pass it to .wait(&#8230;), the code in the second inline &lt;script> block, the calls to &#8220;framework.init()&#8221; and &#8220;framework.doSomething()&#8221;, those scripts do not yet exist (are undefined) at the moment the inline script block in question executes (which would be immediately after the first parse of the $LAB chain, but before either of its scripts have arrived).</p>
<p>So, we have to put THAT code into a .wait(&#8230;) as well, so that it waits to be parsed/executed until the right time.</p>
<pre style="background-color:#ddd;">
&lt;script>
  $LAB
  .script("framework.js")
  .script("myscript.js")
  .wait(function(){
     myscript.init();
<strong>
     framework.init();
     framework.doSomething();
</strong>
  });
&lt;/script>
</pre>
<p>We could do two separate .wait(&#8230;) calls, but that&#8217;s unnecessary in this example, so I just combine the two sets of inline code into one wait() function.</p>
<h2>Think asynchronously</h2>
<p>The key issue is the difference between immediately executing code (like in the original inline &lt;script> tags) and the need to defer asynchronously executing code, by wrapping it in an anonymous function reference. This is because LABjs, by definition, loads scripts asynchronously, as opposed to regular &lt;script> tags which are synchronous.</p>
<p>It may take a couple of tries before you wrap your brain completely around this stuff. But the basic pattern you can default to applying when replacing &lt;script> tags with LABjs calls is this:</p>
<ol>
<li>For every &lt;script src=&#8221;&#8230;&#8221;>&lt;/script> tag you are replacing, you should have a &#8220;.script(&#8230;)&#8221; call</li>
<li>For every &lt;script>&#8230;/*inline code*/&#8230;&lt;/script> inline script block with code in it, we need a &#8220;.wait(function(){ &#8230; })&#8221; call to wrap around the code</li>
</ol>
<p>Hopefully that helps clear up some confusion you may run into!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.getify.com/2009/11/labjs-how-to-deal-with-inline-code/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>LABjs: why not just concat?</title>
		<link>http://blog.getify.com/2009/11/labjs-why-not-just-concat/</link>
		<comments>http://blog.getify.com/2009/11/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[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 times, [...]]]></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>
]]></content:encoded>
			<wfw:commentRss>http://blog.getify.com/2009/11/labjs-why-not-just-concat/feed/</wfw:commentRss>
		<slash:comments>5</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 @ 2010-09-10 12:16:00 -->