<?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</title>
	<atom:link href="http://blog.getify.com/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>Default favicon and robots</title>
		<link>http://blog.getify.com/default-favicon-and-robots/</link>
		<comments>http://blog.getify.com/default-favicon-and-robots/#comments</comments>
		<pubDate>Tue, 19 Apr 2011 20:29:32 +0000</pubDate>
		<dc:creator>getify</dc:creator>
				<category><![CDATA[Misc]]></category>
		<category><![CDATA[Performance Optimization]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[mod-rewrite]]></category>
		<category><![CDATA[performance]]></category>

		<guid isPermaLink="false">http://blog.getify.com/?p=792</guid>
		<description><![CDATA[This is a quick post to share something I experimented with today to figure out. Perhaps it&#8217;ll be helpful to you on your sites. I finally got fed up with the fact that, no matter what, when I have a blank new site, the browsers (and search engines) all insist on requesting a favicon.ico and [...]]]></description>
			<content:encoded><![CDATA[<p>This is a quick post to share something I experimented with today to figure out. Perhaps it&#8217;ll be helpful to you on your sites.</p>
<p>I finally got fed up with the fact that, no matter what, when I have a blank new site, the browsers (and search engines) all insist on requesting a favicon.ico and a robots.txt file. In general, I want there to be some default files for those two, when I have a blank site. Only if I really care to override do I want a custom file for either.</p>
<p>So, I created a default favicon.ico <img class="alignnone size-full wp-image-793" title="favicon" src="http://getiblog.2static.it/wp-content/uploads/2011/04/favicon.png" alt="HTML" width="16" height="16" /> (taken directly from the awesome <a href="http://www.famfamfam.com/lab/icons/silk/" rel="nofollow">FamFamFam Silk Icons set</a>) file, and a default robots.txt file:</p>
<pre class="code">
# robots.txt
#
User-agent: *
Disallow:
</pre>
<p>I uploaded these files into a central location on my server (not necessarily web accessible). Now, how do I get all my dozens of sites to use one of these files by default, if the site in question doesn&#8217;t already have that file defined? Took some experimentation, but I used some &#8220;mod_rewrite&#8221; and &#8220;Alias&#8221; trickery to get it done.</p>
<p>Here&#8217;s the relevant excerpt from my Apache configuration:</p>
<pre class="code">
Alias /default-favicon.ico /path/to/favicon.ico
Alias /default-robots.txt /path/to/robots.txt

&lt;FilesMatch "(favicon\.ico|robots\.txt)$">
        RewriteEngine on
        RewriteCond %{REQUEST_FILENAME} favicon\.ico$ [NC]
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteRule .* /default-favicon.ico [L]

        RewriteCond %{REQUEST_FILENAME} robots\.txt$ [NC]
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteRule .* /default-robots.txt [L]
&lt;/FilesMatch>
</pre>
<p>That&#8217;s it! First, I use a &#8220;FilesMatch&#8221; clause to restrict my URL rewriting to only the two files I care about. Then, I use a mod-rewrite ruleset, <strong>only if the requested file isn&#8217;t found</strong>, to replace the request for &#8220;/favicon.ico&#8221; with &#8220;/default-favicon.ico&#8221; (and similarly for robots.txt). Then, notice that I have set up two &#8220;Alias&#8221; statements (&#8220;Alias&#8221; comes from the mod-alias module), which map those default-* filenames to the actual default files in the central location. Apache first processes the mod-rewrite ruleset, and then re-passes through URL parsing, where it then picks up on the Alias.</p>
<p>You may ask, why can&#8217;t you just use the mod-rewrite &#8220;RewriteRule&#8221; to map directly to the proper file location? I dunno, I wish I could. But apparently, mod-rewrite insists on paths for &#8220;RewriteRule&#8221; being relative to the DOCROOT of the site in question, rather than to the filesystem. So &#8220;/default-robots.txt&#8221; really means &#8220;/path/to/site-docroot/default-robots.txt&#8221;. The &#8220;Alias&#8221; takes care of mapping from that new bogus location to the real location of the default files. Bam. Works.</p>
<p>Hope that&#8217;s maybe helpful to some of you. No more uncacheable 404&#8242;s for favicon.ico and robots.txt. No more bogging down of my error logs. Yay.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.getify.com/default-favicon-and-robots/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Desktop vs. Mobile&#8230; an exploration of site delivery</title>
		<link>http://blog.getify.com/desktop-vs-mobile-exploration/</link>
		<comments>http://blog.getify.com/desktop-vs-mobile-exploration/#comments</comments>
		<pubDate>Thu, 24 Mar 2011 03:14:09 +0000</pubDate>
		<dc:creator>getify</dc:creator>
				<category><![CDATA[Misc]]></category>
		<category><![CDATA[Performance Optimization]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[mobile]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[ux]]></category>

		<guid isPermaLink="false">http://blog.getify.com/?p=783</guid>
		<description><![CDATA[So, I&#8217;m nearing the full beta release of a desktop site/webapp I&#8217;ve been building for awhile. And one thing I realized is that the design/UX of the site works great for desktop and probably is too much for most smartphones (maybe not ipads) to really be that usable. So, it occurs to me ways that [...]]]></description>
			<content:encoded><![CDATA[<p>So, I&#8217;m nearing the full beta release of a desktop site/webapp I&#8217;ve been building for awhile. And one thing I realized is that the design/UX of the site works great for desktop and probably is too much for most smartphones (maybe not ipads) to really be that usable. So, it occurs to me ways that I could rearrange and simplify (greatly) the UX (the JS and the CSS, and some of the HTML) for a better mobile experience.</p>
<p>Figuring out how to arrange a site more vertically (for mobile smartphones) and with less complication (more touch-friendly, instead of mouse oriented) is doable, and not really the point of this post. The point of this post is, given these two different site experiences, how should I serve them to different devices?</p>
<p>It&#8217;s clear that a smartphone (~320&#215;480 type screen size) probably should get my mobile-optimized UX design. This means that there&#8217;s a whole bunch of CSS and JS for my desktop site that doesn&#8217;t need to be served to those devices (because that would be a lot of wasted bandwidth). Conversely, the mobile site will certainly have some CSS and JS that will only be for the mobile-optimized experience, and would be wasted/ignored for the desktop-optimized site.</p>
<p>But, what about the trend of &#8220;in-the-middle&#8221; devices like tablets. It&#8217;s pretty clear that a lot of them are nearly as capable as their desktop counter-parts. Capability aside, though, my primary concern is, will my desktop design UX be appropriate on a tablet? My guess is, yes, it&#8217;d be more appropriate than my slimmed-down mobile site UX design. So, for tablets, and for desktops, the default behavior should be the full site, and for the much smaller screens, the mobile design should be the default.</p>
<p>Notice I said default. I mean it. I&#8217;m only seeking to optimize the choice of the default experience. On BOTH versions of the site, a link will be present which will let someone manually toggle to change to the other experience. If my guess or default is wrong, the user will be able to switch. And do so with a cookie (if possible), so that the switch is remembered from then on.</p>
<p>So, what it comes down to is, I&#8217;m basically wanting to fork the two site versions based on screen dimensions (and to some extent, PPI resolution). The two site versions have some overlap, but it seems like there&#8217;s enough that&#8217;s unique to each, that one is not really a sub-set or super-set of the other. And for the sake of this discussion, let&#8217;s just assume that my desktop site is 300k (including ALL resources), my mobile site is 50k, and the overlap between the two is about 15k (content the same, some JS the same, a few images the same, etc).</p>
<p>So, what are my options?</p>
<ol>
<li>Full UA sniffing on the server, serving only one version of the site (300k) or the other (50k)</li>
<li>Serve a big combined site (~335k) with content/css/js for both sites all being sent, and use CSS3 media-queries to simply show/hide various bits of content from each type of device/computer as screen geometry dictates. (AKA, &#8220;responsive design&#8221;, &#8220;responsive &#8230;&#8221;, etc)</li>
<li>JavaScript logic served at first page-load, to determine screen geometry, and then take appropriate action to load the appropriate site content/css/js. (300k or 50k)</li>
</ol>
<h3>Pros/Cons</h3>
<p>For (1), the obvious con is having to maintain a full UA sniffing. Why? because the server doesn&#8217;t know the screen size (not in the UA string). So, I&#8217;d have to construct (or use existing) UA sniffing logic for all the various mobile browsers&#8230; and moreover, I&#8217;d have to account for tablets in that checking, too. If the iPad were the only tablet, that wouldn&#8217;t be so bad. But there&#8217;s now dozens of different tablet models on the near horizon. That means lots of complicated UA sniffing to correctly identify each one/type. </p>
<p>And, it means committing to keeping up that UA sniffing for all new types of &#8220;in-the-middle&#8221; devices, making decisions individually based on each. For instance, is a 7&#8243; device big enough? What about a 5&#8243; or 6&#8243; version of the same device (will it&#8217;s UA even be different)? What about the 9&#8243; or 10&#8243; versions? That&#8217;s going to mean LOTS of testing and maintenance overhead to get that right and keep it right going forward. Ugh.</p>
<p>But the big pro is, if the UA sniff (aka &#8220;guess&#8221;) is correct, the user only downloads exactly what&#8217;s necessary for their device. Mobile users get only 50k, and Desktop or &#8220;in-the-middle&#8221; users only get 300k.</p>
<p>For (2), the obvious con is the larger size of the full combined set of resources (335k). For a desktop, that&#8217;s about 12% more than it really needs. For mobile, though, that&#8217;s about 570% more than it really needs. Are there tricks to reduce the unnecessary loading? Sure. But the point is, a lot of HTML, and a lot of JS, and at least some CSS, will get loaded unnecessarily, especially in the mobile case, where bandwidth is likely to be more of a limiting factor. This just doesn&#8217;t feel like the right solution.</p>
<p>Another con is that media queries have good, but not universal, support. Namely, no IE supports it until IE9. That means all mobile IE&#8217;s are left out of the party. Unless you use something like <a href="https://github.com/scottjehl/Respond">Respond</a> from <a href="http://twitter.com/scottjehl">Scott Jehl</a>, which patches IE6-8 (and probably others) for media-query support, specifically for width/height geometry. But that adds a little extra weight (3.5k before gzip). So, it&#8217;s something to consider.</p>
<p>Of course, clearly the huge pro is that you avoid all UA sniffing and all the terrible junk that comes along with it.</p>
<p>For (3), the obvious con is that for non-JavaScript (like mobile devices that don&#8217;t have JS enabled), they&#8217;d basically be totally left out. Of course, a &lt;noscript> tag could probably use some redirect (meta tag or manual &lt;a> link) to give such a user a way forward. That&#8217;s workable, but it&#8217;s less than ideal. Then again, do I even care if my non-JS visitors can get to my site? For some sites, they don&#8217;t care. For me, however, I do care. I probably need a non-JS solution.</p>
<p>The pro is, like with (1), only one version of the site is served. And even more likely to be correct than in (1), with a lot less work/maintenance.</p>
<p>Bottom line, none of these 3 options is really great. I&#8217;m sure a lot of sites employ something like them for this type of functionality. But they all seem like they&#8217;re sub-optimal, for various reasons.</p>
<h3>So what should I do?</h3>
<p>Let me just say up front, I&#8217;ve not fully decided, nor do I really know for sure the best answer. This post is basically just to explain my experimental/explorative thoughts on the topic, and to solicit feedback from the community on what they think.</p>
<p>I got to thinking, what if CSS3 media queries could be used to do the checking on the screen&#8217;s size, and without any JavaScript, set a cookie that would let the server know which site version to serve, on the next refresh.</p>
<p>So, here&#8217;s how I might accomplish that.</p>
<ol>
<li>On first request to server, check if a cookie is set for site version. If so, respect it, and deliver the proper site directly. If not, use basic UA sniffing to identify mobile webkit and a few other well known mobile browsers. Don&#8217;t worry at all about device type, just identify common mobile browsers. If it seems like a mobile device from this coarse guess, serve up a &#8220;check&#8221; page. If not, assume the best, and serve up the full desktop site. Again, set a cookie for next time.</li>
<li>In the &#8220;check&#8221; page, have a few bits of inline &lt;style>, using CSS3 media queries, to do the screen geometrics testing. In each block, have it make a background-image request, with a particular parameter in it, indicating to the server the screen size category. The server then sets a cookie appropriately. In theory, only one of these two requests should go out, and if cookies are enabled, then it should identify it fairly reliably.</li>
<li>Include a meta-refresh tag, and JavaScript redirect (just in case), and lastly an &lt;a> link for the user to follow to refresh the page. If the cookie setting worked, this refresh should now serve the appropriate version of the site.</li>
</ol>
<h3>Gotchas</h3>
<p>This idea is not perfect, by any means. There&#8217;s plenty of pitfalls. </p>
<p>For instance, if the browser doesn&#8217;t support cookies, this won&#8217;t work. Then again, for *my* site, I think I want to require cookies, so perhaps that&#8217;s not a deal breaker. I could detect cookie-setting failure, and display a message to the user that the site requires cookies to proceed. Or I could just default to either version of the site if the cookie setting failed, and just let the user figure out that it&#8217;s not gonna work as expected, in some respects.</p>
<p>Also, there&#8217;s the case where on mobile, there was a redirect that happened. This is an unfortunate extra delay/bandwidth/etc. But, I&#8217;m hoping that this refresh/redirect that occurs is less penalty than shoving 570% too much HTML/JS down the pipe on the first view.</p>
<p>What about if the browser doesn&#8217;t request background-images? Perhaps the CSS could also use content:after to create an &lt;img> tag to force the request.</p>
<p>How do I force the meta-refresh/JS redirect/link clicking to &#8220;wait&#8221; for the cookie setting to occur after the background-image response comes back? For JS, this is easy, just poll for the image to finish loading. For the meta-refresh and the link clicking, not so much. There&#8217;s a few quirky ideas I could explore, but I&#8217;m not really entirely certain how to force this part to work correctly. But I&#8217;m also not convinced that it has no solution. And remember, it might only fail if the user doesn&#8217;t have JS&#8230; so as a fallback, the meta and links could always force one version (regardless of cookie), whereas the JS waits for the cookie, and does a refresh.</p>
<p>I&#8217;m sure there are other pitfalls I&#8217;m not realizing yet. I&#8217;d love to get some feedback from you, the reader. Am I crazy? Is this over architecting? Does this have promise? Will I fail?</p>
<p>Please, though, keep in mind a few things when providing feedback:</p>
<ol>
<li>Having already built the full site, and at least sketched out what the mobile site will look like, radical/significant changes to the design of either are not only impractical, but irrelevant. Please don&#8217;t comment if this is your suggestion. The spirit of what I&#8217;m asking is, making the best with my current situation, which is basically two site versions.</li>
<li>UA sniffing is, in my opinion, generally evil. I want to avoid it as much as possible. I only introduce it in the above idea because it helps the &#8220;guess&#8221; and reduces to some extent how many people get the &#8220;check&#8221; page (and its delays, thereof). And, of course, the simple basic UA sniffing I&#8217;m talking about is orders of magnitude easier to write/maintain compared to full-blown UA sniffing.</li>
<li>I am forking primarily based on my intended UX for small screens vs. big screens. I&#8217;m not forking for JS vs. non-JS, or because of low-powered/incapable devices, etc. I&#8217;m only forking based on screen geometry, because of its direct correlation to usability of layout.</li>
</ol>
<p>That&#8217;s it. I hope to hear some great ideas. Thanks!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.getify.com/desktop-vs-mobile-exploration/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>&#8220;(pre)Maturely Optimize&#8230;&#8221; revisited</title>
		<link>http://blog.getify.com/pre-maturely-optimize-revisited/</link>
		<comments>http://blog.getify.com/pre-maturely-optimize-revisited/#comments</comments>
		<pubDate>Thu, 17 Feb 2011 06:40:05 +0000</pubDate>
		<dc:creator>getify</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Performance Optimization]]></category>
		<category><![CDATA[benchmarking]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[optimization]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[profiling]]></category>
		<category><![CDATA[script junkie]]></category>

		<guid isPermaLink="false">http://blog.getify.com/?p=761</guid>
		<description><![CDATA[I wrote an article for Script Junkie (Microsoft) awhile back, and it was just published this week: (pre)Maturely Optimize Your JavaScript. In it, I make several against-the-grain assertions, which not surprisingly have ruffled quite a few feathers. To start out with, I&#8217;m attacking head-on the prevailing &#8220;fear&#8221; around doing anything in your code that even [...]]]></description>
			<content:encoded><![CDATA[<p>I wrote an article for <a href="http://scriptjunkie.com">Script Junkie</a> (Microsoft) awhile back, and it was just published this week: <a href="http://msdn.microsoft.com/en-us/scriptjunkie/gg622887.aspx">(pre)Maturely Optimize Your JavaScript</a>. In it, I make several against-the-grain assertions, which not surprisingly have ruffled quite a few feathers.</p>
<p>To start out with, I&#8217;m attacking head-on the prevailing &#8220;fear&#8221; around doing anything in your code that even remotely <em>looks</em> like optimization, because the magical &#8220;Premature Optimization is the root of all evil&#8221; fairy will come and slap you silly. I argue that in fact &#8220;<strong><em>Immature</em></strong> Optimization is the root of all evil&#8221;, and what we should as devs be most concerned about is learning how to optimize <strong><em>maturely</em></strong>. Mature optimization requires engineer-like thinking, critical reasoning skills, pragmatic wisdom, and above all, the sense of how to properly achieve balance.</p>
<p>Contrary to some of the negative outcry from a few vocal members of the community, I do not think I&#8217;m advocating for anything that would rightly be considered &#8220;premature&#8221;. Some people say that any optimization is &#8220;premature&#8221; if you haven&#8217;t first seen that code fail under load in real conditions. To me, this is like learning to drive by driving first, having accidents, and correcting your driving as you go along.</p>
<p>That doesn&#8217;t mean data and benchmarking is not important &#8211;of course it is.</p>
<h3>Maturity</h3>
<p>But it <em>equally</em> means that the mature and right thing to do is to <em>ALSO</em> be aware of common pitfalls before you hit them, and strive to write code that avoids those bad patterns. Many developers shy away from such approaches because they (I believe wrongly) assume that all &#8220;code optimization&#8221; leads to uglier or harder to maintain code. While this may sometimes be true, to an extent, it&#8217;s not a hard objective fact, and there&#8217;s lots of optimizations that can become <em>default</em> in your coding style that do not significantly detract from the style of your code.</p>
<p>In fact, I believe the 7 comparison snippets (before and after) that I show in the article illustrate that, with a few very minor changes, changes which do not cause the code to become completely unmaintainable, you can improve the performance of your code, sometimes by just a tiny amount, or sometimes by a huge amount.</p>
<p><strong>In NO case would I advocate <em><u>significantly</u></em> uglier or harder to maintain code for only a 3-10% increase in speed, in code that is not very critical.</strong> But a balanced, performance-savvy perspective on every line of code you write will tend to help you avoid the pitfalls, and let you focus your valuable energies on much more important tasks.</p>
<p>Also, notice: I am <strong>not</strong> focusing on esoteric and minute micro-performance details (as some do, and many assumed I was). I made no mention of things like <code>array.push()</code> vs. <code>array[array.length]</code>, or <code>str += "..."</code> vs. <code>str = arr.join()</code>, or <code>++i</code> vs. <code>i++</code>, or <code>for (i=0; i &lt; arr.length; i++) {...}</code> vs. <code>for (i=0, len=arr.length; i&lt;len; i++) {...}</code>, etc etc etc.</p>
<p>The optimizations I focused on were more broad pattern and algorithmic in nature, rather than comparing native operators and functions to each other &#8212; a fruitless task these days, with the browser speed wars still raging strong.</p>
<h3>Profiling, &#8220;profiling&#8221;</h3>
<p>If you already have existing code that&#8217;s a potential candidate for some optimization TLC, as Paul Irish pointed out to me, the prudent thing to do is of course to employ a script profiler. There are several tools that can profile run-time JavaScript performance &#8212; for instance, IE9&#8242;s Developer Tools includes a built-in profiler. Just yesterday, I used it to help my co-workers track down a critical performance bug in one of our client projects.</p>
<p>I wish I had mentioned the process of profiling specifically in the Script Junkie article. It wasn&#8217;t really the point of the article &#8212; the point was, once you&#8217;ve identified a block of code to attack, here&#8217;s some easy ways to do it &#8212; but it would have been helpful to talk about briefly. Paul was right to point out that omission.</p>
<p>On the other hand, the other implied goal of my article was to say that sometimes, our own brains and critical thinking skills can be effective at &#8220;profiling&#8221; the code we&#8217;re writing, as we write it. I regularly find myself halfway through an implementation, and I realize that something I&#8217;ve done is likely to lead to some performance hit later. I find that it&#8217;s usually not too difficult to adjust my approach right as I&#8217;m coding.</p>
<p><strong>How do I so easily recognize a performance anti-pattern as I&#8217;m writing it?</strong> I understand and code with a performance-savvy mentality as my default. I also have plenty of previous experience to inform avoiding repeating mistakes. And most of all, I subscribe to the belief that I should always be trying to learn from others who are knowledgeable and passionate about performance, to gain from their experience and wisdom as well.</p>
<p>This is the same mentality I&#8217;m advocating for other developers to adopt. I call <em>that</em> &#8220;Mature Optimization&#8221;.</p>
<h3>Refactoring</h3>
<p>I&#8217;ve made the claim a number of times, and I stand by it: <strong>The TCO (Total Cost of Ownership) for non-performant code is higher than for performant code.</strong> In other words, pay a little bit now, by way of taking the effort to write performant code (where practical), the first time, or pay more later, if/when you have to refactor that code to address performance concerns.</p>
<p>First of all, in the corporate world (of which i&#8217;ve held many such jobs), you often don&#8217;t ever get the second chance to come back and fix that poorly written code that you have to just throw together to get it out on deadline. We tell ourselves we&#8217;ll always come back and fix the code later, but in reality, we often never get to. And if we <em>do</em> get to come back to it, it&#8217;s usually under extreme pressure because something fell apart in production under real load, and now your boss is pissed at you.</p>
<p><strong>Not only does performance refactoring cost, in general, &#8220;double&#8221; the time in coding (coding it once, then coding it again), but it also costs a lot more time when unfortunate but often inevitable regressions are introduced and must also be corrected.</strong> Performance &#8220;refactoring&#8221; is more risky.</p>
<p>And why do I make that assertion?</p>
<p>Because unit-testing is <em>not</em> the de facto standard in the corporate world like it should be. In fact, of the dozen or so jobs I&#8217;ve held in the corporate web-application industry in my career, maybe 1 or 2 of them actually took unit-tests seriously. Most of the time, full integration tests (and not even comprehensive) were the best tests we could ever get our boss to approve us time to write.</p>
<p>I know we&#8217;d all like to sit on happy island where unit-testing (or TDD) is a reality and we all have 100% test coverage. But it isn&#8217;t that way in the real world, by and large.</p>
<p><strong>When you don&#8217;t have proper unit-tests, performance &#8220;refactoring&#8221; is very risky.</strong> The conditions under which you are forced to do it conspire against you, and you&#8217;re just bound to mess something up, usually in a subtle way you don&#8217;t realize just then.</p>
<p>And, btw, <em>even if</em> you had a full regression test-suite that ran, and immediately notified you that your &#8220;refactor&#8221; just broke something, you still have to spend more time (often costly time) tracking down the cause of that regression, and the regression <em>that fix</em> causes, and so on&#8230; down the rabbit hole we go. </p>
<p>It&#8217;s crazy to think that internally refactoring a function&#8217;s implementation details would cause other side effects, right? Sure, because in the corporate world, we get plenty of time to write 100% high quality code with no shortcuts or assumptions. We never stoop to using a quick global variable instead of figuring out the proper closure-scoping approach, when our boss is breathing heavy down our neck. Our code is always perfectly self-contained and well-patterned, right? </p>
<p>Except, no it isn&#8217;t, because that&#8217;s why we have this performance bug cropping up in the first place &#8212; because we had to cut corners to get code out the door.</p>
<h3>Benchmarks</h3>
<p>Some vocal critics have accused my code snippets in my article as being &#8220;premature optimization&#8221; because the improvements I suggest are &#8220;micro&#8221; or won&#8217;t have any noticeable impact on performance. I disagree with that assertion. And I created some <a href="http://jsperf.com">jsPerf.com</a> tests to illustrate.</p>
<p>The first versions of my test were a little rough and ill-formed, and Rick Waldron pointed out those flaws. I believe I&#8217;ve adjusted these tests to more accurately depict the point that each snippet comparison in the article was trying to make.</p>
<p><strong>NOTE:</strong> these tests are not going to look like your typical tests where you are comparing two native operators or something low-level like that. In several cases, the algorithms between each test case are intentionally quite different. It <em>should</em> be obvious that one will run much quicker than the other, because it&#8217;s doing a lot less (or a lot different) kind of task. The whole basis for these examples in the article is to show how a common, natural code pattern that&#8217;s perfectly semantic and self-descriptive or &#8220;object-oriented&#8221; or whatever, can suffer from (sometimes subtle) performance degradation. And <em>sometimes</em>, an effective way to improve performance is to think about a slightly different pattern or algorithmic approach. I&#8217;m trying to help you &#8220;see the forest above the trees&#8221;.</p>
<ol>
<li><a href="http://jsperf.com/scriptjunkie-premature-1/3">test case: function call, inner loop</a></li>
<li><a href="http://jsperf.com/scriptjunkie-premature-2">test case: bulk operations or iterators</a></li>
<li><a href="http://jsperf.com/scriptjunkie-premature-3">test-case: $(this) or collection-faking</a></li>
<li><a href="http://jsperf.com/scriptjunkie-premature-4">test-case: scope lookup, cached or not</a></li>
<li><a href="http://jsperf.com/scriptjunkie-premature-5">test-case: prototype chain lookup, cached or not</a></li>
<li><a href="http://jsperf.com/scriptjunkie-premature-6">test-case: nested property lookup, cached or not</a></li>
<li><a href="http://jsperf.com/scriptjunkie-premature-7">test-case: dom append or dom-fragment append</a></li>
</ol>
<p>Each of those tests has a table below it for the captured/averaged <a href="http://browserscope.org">Browserscope</a> test-run results, per browser. For instance, consider the test results (so far) for the first test-case (&#8220;function call, inner loop&#8221;):</p>
<p><img src="http://getiblog.2static.it/wp-content/uploads/2011/02/test1-results.png" alt="" title="test1-results" width="600" height="101" class="aligncenter size-full wp-image-762" /></p>
<p>Consider the Chrome 9 results: 14,101 operations/sec vs. 15,607 operations/sec. That&#8217;s a difference of 1,506 operations/sec, which is 10.7% faster. What did I do between those two tests? I simply inlined the <code>isOdd()</code> implementation into the loop, instead of as a function call. Is 10.7% life shattering or huge? No, probably not. But it&#8217;s an example of a very common coding pattern which <em>is</em> slower. With slightly more thought, in the case where it was possible/appropriate to do so, we can speed things up by 10.7% and not cost much by way of development time, nor is the code appreciably harder to maintain.</p>
<p>And, if you find that you are writing code that is a little uglier, or maybe is a little less self-explanatory, and you&#8217;re worried that this code may cause you (or some other dev) a maintenance problem later, there&#8217;s a sure-fire easy solution: <strong>WRITE A FRIGGIN&#8217; COMMENT TO EXPLAIN WHY THE CODE NEEDS TO BE THAT WAY.</strong></p>
<p>In fact, let me just say this: if you follow my advice and code with performance patterns in mind from the start, and you find yourself writing a piece of code that is just horribly uglier and no amount of comments can adequately explain why it is that way&#8230;. </p>
<p><strong>STOP and back up. You have my permission to code NON-performantly in that situation, if you simply can&#8217;t do so in a reasonably clean or comment-explainable way.</strong> Sheesh, was that so hard? Am I really a crazy lune?</p>
<h3>Summary</h3>
<p>Quit listening to all the negative hype about &#8220;premature optimization&#8221;. It&#8217;s mostly hot air with no substance. It&#8217;s a bunch of developers following what other developers say, mostly blindly. And the few developers who actually have a reason for rallying against &#8220;premature optimization&#8221;, they&#8217;re probably mad about it not because the optimization was <em>premature</em>, but because it was <em><strong>immature</strong></em>.</p>
<p>So, let&#8217;s all just try to grow up and mature a little bit with how we approach performance-savvy coding. We&#8217;ll all get a lot more quality code written that way.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.getify.com/pre-maturely-optimize-revisited/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>On Script Loaders</title>
		<link>http://blog.getify.com/on-script-loaders/</link>
		<comments>http://blog.getify.com/on-script-loaders/#comments</comments>
		<pubDate>Thu, 16 Dec 2010 20:36:13 +0000</pubDate>
		<dc:creator>getify</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Performance Optimization]]></category>
		<category><![CDATA[browsers]]></category>
		<category><![CDATA[ControlJS]]></category>
		<category><![CDATA[HeadJS]]></category>
		<category><![CDATA[labjs]]></category>
		<category><![CDATA[optimization]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[script loader]]></category>
		<category><![CDATA[standards]]></category>

		<guid isPermaLink="false">http://blog.getify.com/?p=739</guid>
		<description><![CDATA[Comment Two recent projects have come out that attempt to address the &#8220;dynamic script loader&#8221; use case: HeadJS and ControlJS. Since I&#8217;m the creator of LABjs, a general, all-purpose, performance-oriented dynamic script loader that&#8217;s been around for about a year and a half now, and is well-known enough to be in use on several major [...]]]></description>
			<content:encoded><![CDATA[<h3>Comment</h3>
<p>Two recent projects have come out that attempt to address the &#8220;dynamic script loader&#8221; use case: <a href="http://headjs.com/" rel="nofollow">HeadJS</a> and <a href="http://stevesouders.com/controljs/" rel="nofollow">ControlJS</a>. Since I&#8217;m the creator of <a href="http://labjs.com">LABjs</a>, a general, all-purpose, performance-oriented dynamic script loader that&#8217;s been around for about a year and a half now, and is well-known enough to be in use on several major sites, including <a href="http://twitter.com">Twitter</a>, <a href="http://vimeo.com">Vimeo</a>, and <a href="http://zappos.com">Zappos</a>, many people ask my opinions when new entries into this space arise.</p>
<p>I&#8217;ve been hesitant to rush to negative judgement on either one, because I believe it&#8217;s important to encourage experimentation and progress in this area, for the sake of the greater web. But I do think it&#8217;s important to shed a little bit of light onto both projects and explain some concerns I have with their approach. I respect the authors of both libraries, so I hope they will take my ramblings here as constructive criticism rather than an attack.</p>
<h3>ControlJS: backstory</h3>
<p>ControlJS comes from the immensely experienced and talented <a href="http://stevesouders.com">Steve Souders</a>, who leads performance efforts for Google. For readers who aren&#8217;t aware, when I first was building LABjs back in 2009, Steve stepped in and offered some very helpful and timely advice and collaboration, and I credit much of LABjs&#8217; success since to Steve&#8217;s wisdom and experience.</p>
<p>Recently, though, Steve has focused in a different direction than was necessarily the focus back then. His focus is now more aimed at delaying all script loadings until after the rest of the page content has loaded, whereas LABjs&#8217; goal was to simply allow easy parallel loading of scripts (instead of blocking behavior) right along side the rest of the page content. In my opinion, there are some scripts which are less important, like Google Analytics, social sharing buttons, etc. And I whole heartedly agree with &#8220;deferring&#8221; that code&#8217;s loading until &#8220;later&#8221;, to not take up precious valuable bandwidth/connections/cpu.</p>
<p>But there&#8217;s also a lot of JavaScript that is just as important as the content it decorates, and to me, the idea of delaying that code by a noticeable amount will lead, in general, to proliferation of a distasteful visual effect I call <strong>&#8220;FUBC&#8221; (Flash of Un-Behaviored Content)</strong>. In other words, we&#8217;ll see pages that flash up raw text content, only to swap out a moment or two later into the widgetized and JavaScript stylized version of the page, where the content is in fancy tab-sets, modal dialogs, etc. </p>
<p>To be clear, any dynamic script loader can create this effect unintentionally, including LABjs. But what ControlJS appears to be intentionally doing is delaying scripts even longer past when content is visible/useable, which will exacerbate this FUBC problem quite a bit.</p>
<p>There are of course ways to mitigate this, using default/inline CSS rules and &lt;noscript> tags (a technique I talk about on the LABjs site), but if you hide all the raw content with CSS and don&#8217;t re-display it until the JavaScript is present, you lose <strong><em>ALL</em></strong> of the benefit of deferring that JavaScript logic to let the content load quicker. The goal is admirable, but I think it will end up being neutral or worse UX for most sites.</p>
<p>This is a tenuous and difficult UX balance that sites need to consider carefully. I do not endorse Steve&#8217;s suggestions, that basically all sites should move to this model. It makes sense for some of them, if they intentionally design their UX that way. But it&#8217;s by far not optimal for a lot of sites, and using his suggestions will trade out performance for really sub-optimal user experience during page-load if not done with caution and reserve.</p>
<p>So, that is the context under which Steve presents us ControlJS. It&#8217;s an attempt to create a script loader that more closely models his view of how page-loads should work (that scripts should all defer loading and execution until all content is finished). If you agree with him, and aren&#8217;t worried about FUBC (or have already carefully thought about and designed around it), ControlJS is something to at least consider. But if you&#8217;re just planning to drop in ControlJS to an existing site, I think this is possibly a <em>big</em> mistake and the wrong direction for the web to head in.</p>
<p>So, I simply chose to disagree with Steve on this point, and we&#8217;re now focusing on different goals.</p>
<h3>ControlJS: approach</h3>
<p>In addition to my UX concerns with Steve&#8217;s approach to page-load optimization that&#8217;s embodied in ControlJS, I have some problems with the functional approach he&#8217;s taken as well.</p>
<h4>User-agent</h4>
<p>First, ControlJS relies on browser user-agent sniffing to choose different loading techniques for different browsers. I have been a very vocal critic of user-agent sniffing, even to the <a href="http://www.nczonline.net/blog/2010/01/12/history-of-the-user-agent-string/">opposition</a> of brilliant guys like <a href="http://twitter.com/slicknet">Nicholas Zakas</a>.</p>
<p>I&#8217;m not going to rehash the whole debate of user-agent sniffing. I simply won&#8217;t use it, and I think most people agree that it&#8217;s a bad choice. Feature-detection is far preferable. In between the two, but I still think better than user-agent sniffing by an important amount, is <strong>browser-inferences</strong>. LABjs uses a couple of browser-inferences (basically, testing for a feature known to be characteristic of only one or a family of browsers), <strong>very reluctantly</strong> as a temporary stop-gap until such a time as the browsers support dynamic script loading use-cases with feature-testable functionality. ControlJS makes no such attempt to be robust or future-thinking on this topic, simply relying on basic user-agent sniffing. This definitely worries me.</p>
<p>Moreover, I&#8217;ve been heavily engaged in trying to petition browsers and the W3C to support native functionality that supports the dynamic script loading use-cases, in a <strong>feature-testable</strong> way. If you&#8217;re unfamiliar with that proposal/effort, take a look at this WHATWG Wiki Page: <a href="http://wiki.whatwg.org/wiki/Dynamic_Script_Execution_Order">Dynamic Script Execution Order</a>.</p>
<p>Mozilla (starting with FF 4b8, due out in a few days) and Webkit (very shortly in their Nightlies) have implemented the `async=false` proposal made there, and done so in a way that&#8217;s feature testable. LABjs 1.0.4 was released a few weeks ago with the new feature-test in it to take advantage of that new functionality when browsers implement it. Eventually, the goal is to deprecate and remove the old hacky browser inferences (and the old hacky browser behavior it activated) in favor of this new (and hopefully soon standardized) behavior.</p>
<p>I asked Steve several times to join in the efforts to advocate for this new feature-testable native functionality to be standardized and adopted by browsers, which I believe will <strong>DRASTICALLY</strong> improve script-loaders&#8217; ability to performantly load scripts into pages. He politely <em>declined</em> to participate, and suggested my efforts were misguided. And instead, he released ControlJS using old and sub-optimal user-agent sniffing in its place. This is obviously not how I hoped things would progress.</p>
<h4>Preloading</h4>
<p>During the development of the original 1.0 release of LABjs back in 2009, I consulted several times with Steve on various trade-offs that had to be made to get a generalized script loader to address all the various use-cases. </p>
<p>The biggest problem I faced was that some browsers (namely IE and Webkit) offered no direct/reliable way to load scripts in parallel but have them execute in order, which is important if you have dependencies (like jQuery, jQuery-UI, and plugins, etc). This is especially difficult to do if you are loading any or all of those scripts from a remote domain (like a CDN), which is of course quite prevalent on the web these days.</p>
<p>I developed and tested a trick I call &#8220;cache-preloading&#8221; (something which is now getting a lot of attention from various script loaders), which was basically a way to handle this. It was openly admitted to be a hack, sub-optimal, and hopefully something that would be eventually removed from LABjs. </p>
<p>There are various ways to approach this trick, but the fundamental characteristic is that you &#8220;preload&#8221; a bunch of scripts into the browser cache <strong>without execution</strong>, and then you make a second round of requests for those scripts, pulling them from cache, to then execute them. The reason this trick is important to consider is that it has a rather large (and potentially fatal) assumption attached to it: <strong>that all the scripts being requested are served with proper and future expiration headers</strong>, so that they can actually be cached.</p>
<p>Importantly to this post, relying on this assumption was very worrisome to Steve in our discussions back then. He asserted that as much as <del>70%</del> <strong>(Update: maybe 38%, 51%, &#8230;)</strong> of script resources on the internet are not sent with proper caching headers (or none at all), and so for all of those scripts, if they are loaded with a script loader using a &#8220;preloading&#8221; trick, the first load won&#8217;t successfully cache, and the second request will cause a second full load. Not only is that terrible for performance, depending on the script loader&#8217;s internal logic, this assumption failing can create hazardous race conditions.</p>
<p>In addition to the possible double-load, Steve was also worried that even if a script was properly cached, the delay for the second cache hit could be noticeable and bad for large scripts. Again, large script files are very common these days, with the proliferation of advice from people like Steve who suggest concatenating all files into one file (to reduce HTTP requests).</p>
<p>After much discussion and back-and-forth, I reluctantly decided that Steve&#8217;s concerns were valid, and so I added more complexity to LABjs (increasing its size and introducing several ugly hacks) to try to abate this problem. We tenuously agreed that the likelihood was that most of the scripts that are being served with improper headers are being self-hosted (thus on local domains), and that remote domains (like CDNs) would be much more likely to be correctly configured.</p>
<p>I devised a solution where LABjs uses XHR to &#8220;preload&#8221; local scripts, and only falls back to the &#8220;cache-preload&#8221; trick for remote scripts. In addition, I gave people the ability, through config values in the LABjs API, to easily (with a single boolean value) turn off either or both of those preloading tricks, so that developers would be much less likely to accidentally trip over this problem if they indeed had to load a script that had improper caching behavior.</p>
<p>I&#8217;m sure you can imagine my surprise when, this morning, I cracked open Steve&#8217;s code, and I see that he&#8217;s now using the &#8220;cache-preloading&#8221; tricks as the <em>only</em> method, without XHR. In other words, he was really concerned about this problem when he helped me design (and complicate LABjs), but now it&#8217;s not a concern of his. He briefly mentions the assumption of cacheability off-handedly in his blog post, buried in a lot of other text.</p>
<p>I haven&#8217;t seen any research to suggest a radical shift since late 2009 that has most or all script resources now being properly cacheable. So I still consider the concerns that Steve voiced to be quite real and important.</p>
<p>Again, I always considered the &#8220;cache-preload&#8221; to be a hacky last-ditch fallback, and always have intended to remove it as soon as browsers provided a better solution (that&#8217;s happening now, slowly but surely). So, I&#8217;m <strong>quite concerned</strong> to say the least that ControlJS (and HeadJS and others) are latching onto the &#8220;cache-preload&#8221; as their primary (or only) means of handling parallel-load-serial-execute. </p>
<p>Not only are they white-washing over the cacheability assumption, They&#8217;re completely ignoring the recent movement by Mozilla and Webkit to implement the far-preferable `async=false` functionality. I consider this quite unfortunate.</p>
<h4>Brittle Cache-Preloading</h4>
<p>One last note on the &#8220;cache-preload&#8221; tricks: LABjs&#8217; version of the &#8220;cache-preload&#8221; trick was to use a non-standard and undocumented behavior of certain browsers (IE and Webkit) that would fetch a script resource into cache, but not execute it, if the script element&#8217;s `type` value was something fake like &#8220;script/cache&#8221; (instead of &#8220;text/javascript&#8221;).</p>
<p>However, the HTML spec <em>now</em> says that such resources should NOT be fetched. So, Webkit (about a month or two ago) dutifully obeyed the spec and patched their browser to stop fetching them. This means that LABjs&#8217; &#8220;cache-preload&#8221; trick broke entirely in Webkit nightlies. Now, thankfully, Webkit is moving rapidly to adopt the more preferred `async=false` in its place, so hopefully LABjs won&#8217;t be broken in any major Webkit-based browser release.</p>
<p>But there&#8217;s a <em><strong>SUPER IMPORTANT</strong></em> lesson that must be learned here. LABjs got by with non-standard behavior for awhile. But browsers are <em>quickly</em> catching up to the spec/standards. It was almost disastrous for LABjs, had `async=false` not gotten the attention it did, to die a public death because of relying on hacky non-standard behavior.</p>
<p>But ControlJS, HeadJS, and many other script loaders like them are doing the same thing. They aren&#8217;t necessarily using the exact same trick as LABjs used, but they are pinning their entire loading functionality on hacky, non-standard behavior. ControlJS uses the <a href="http://www.phpied.com/preload-then-execute/">&lt;object> preloading hack</a> for some browsers and the `new Image()` hack for other browsers. </p>
<p>Essentially, they&#8217;re relying on the fact that these browsers will fetch the script resource content into cache but not execute it because the container used to do the fetching doesn&#8217;t understand JavaScript. I don&#8217;t know about you, but this sounds to me dangerously like the spec statement of telling browsers not to fetch content with a declared MIME-type the browser can&#8217;t interpret. How long do you think it&#8217;ll be before Webkit, Mozilla, Opera, or IE patch to stop fetching/caching content via &lt;object> or `Image()` that they can&#8217;t interpret?</p>
<p>Some have argued that &lt;object> and `Image()` will always have to fetch such content, because the browser can&#8217;t know the URL won&#8217;t return valid image or object content until after it receives the response. This may be true, the browser may always have to fetch it. <strong>But the browser might chose to discard the contents (and not cache it)</strong> if it sees a content-type that it won&#8217;t consider valid for the requesting container. If I were on a browser dev team, and were coding with the intent of following the spirit of the spec, that&#8217;s exactly the logic I&#8217;d implement.</p>
<p>And I&#8217;d especially do that, even though it may break script loaders, because the spec process (and browsers) are already starting to implement a more direct and reliable approach: `async=false`.</p>
<h4>DOM-ready</h4>
<blockquote><p>
I think itâ€™s ironic that JavaScript modules for loading scripts asynchronously have to be loaded in a blocking manner. From the beginning I wanted to make sure that ControlJS itself could be loaded asynchronously.
</p></blockquote>
<p>I understand and empathize completely with Steve&#8217;s sentiment here. He and I both agreed from day one of LABjs that it&#8217;s unfortunate that you have to &#8220;load some JavaScript so that you can load more JavaScript&#8221;. But at its heart, this is how bootstrapping works, and it&#8217;s a reality.</p>
<p>However, I believe Steve has completely glossed over a really important point (and it kind of ties back to my earlier section on the UX of FUBC): if you asynchronously and dynamically load the loader, and don&#8217;t take special precautions, the loader has no way of knowing (in some browsers, including FF3.5 and before) if the page&#8217;s DOMContentLoaded (aka &#8220;DOM-ready&#8221;) has passed or not.</p>
<p>While the script loader doesn&#8217;t really need to care to much about DOMContentLoaded, some of the scripts that you may be loading do very much care. As I wrote about last year regarding <a href="http://blog.getify.com/2009/11/why-dom-ready-still-sucks/">jQuery, DOM-ready, and dynamic script loading</a>, it&#8217;s very common that people write jQuery code that looks like this:</p>
<pre class="code">
$(document).ready(function(){
   // I know the DOMContentLoaded/DOM-ready event has passed! wee!
});
</pre>
<p>The problem is, jQuery can&#8217;t reliably detect DOMContentLoaded in FF3.5 and before (and a few other obscure browsers) <strong>if</strong> jQuery itself is not loaded statically/synchronously (that is, in a blocking way, so that it&#8217;s loaded before DOMContentLoaded can pass). So, if you just blindly load jQuery dynamically, and it happens to finish loading after DOMContentLoaded/DOM-ready has passed, any code you have in your page that looks like that snippet above will just sit forever waiting, and never fire!</p>
<p>So, LABjs takes advantage of the fact that you are almost certainly going to load &#8220;LAB.js&#8221; file with a normal blocking script tag (I know, counter-intuitive, right!?). Inside of LAB.js, at the very end, is a small little snippet that detects if the page doesn&#8217;t properly have a `document.readyState` property on it (what jQuery uses for detecting DOMContentLoaded in those browsers), and if so, it patches the <em>page</em>.</p>
<p>This has the effect that a few hundred milliseconds later, when jQuery finishes loading (if you&#8217;re using jQuery of course!), even if DOMContentLoaded has already passed, jQuery will properly see the right state, and your code will fire immediately. The page-level hack looks like this:</p>
<pre class="code">

// required: shim for FF <= 3.5 not having document.readyState
if (document.readyState == null &#038;&#038; document.addEventListener) {
    document.readyState = "loading";
    document.addEventListener("DOMContentLoaded", handler = function () {
        document.removeEventListener("DOMContentLoaded", handler, false);
        document.readyState = "complete";
    }, false);
}
</pre>
<p>This is an unfortunate page-level hack that's necessary for FF3.5 and before, for jQuery to be properly loaded dynamically and still have code like that snippet above operate as expected. You can see the code is pretty small and compact, so including it in LABjs doesn't hurt the size/complexity too much. But it works <em>because LABjs typically is loaded statically</em>.</p>
<p>So, does that mean LABjs can't be loaded dynamically and still have jQuery and DOM-ready code work? <strong>No!</strong> It just means that the page-level hack in that snippet needs to be part of whatever little "bootstrapper" code you use to dynamically load LABjs to a page. And it means that THAT code that you use as a bootstrapper for LABjs must itself load statically (like in an inline script-block, etc).</p>
<p>In fact, I advocated a little while back exactly how to dynamically load LABjs and still preserve this whole DOM-ready business with <a href="https://gist.github.com/603980">this snippet</a>.</p>
<p>What concerns me about ControlJS, HeadJS, and almost every other loader out there is that they completely ignore this important point about DOMContentLoaded detection for FF3.5 and below. I know for me, I still regularly use LABjs to dynamically load jQuery, and I still use `$(document).ready(...)` to safely wrap code, and I still support FF3.5. So for me, this DOM-ready protection code is important. Whether it appears in the loader code itself, or in the snippet of bootstrapper code, I think those loaders are really missing something important if they don't include that snippet (or something like it).</p>
<h4>Invalid Markup</h4>
<p>This post is already getting really long (again! I can't be short-spoken even if I try!). So I'm going to at least keep this final section brief, and try to wrap up quickly.</p>
<p>ControlJS is able to achieve its "deferral" of script loading and execution (until after window.onload in fact!) by suggesting that you must change all your script elements in your code to be unrecognizable by the browser loading mechanism.</p>
<p>You change a script tag's `src` attribute to be `cjssrc` instead. This is an invalid attribute name, and will be ignored by the browser. <strong>But it also invalidates your markup.</strong> I consider this to be a bad-practice. At least the attribute could have been `data-src` or something, so that it fits with valid spec attribute naming.</p>
<p>Secondly, ControlJS requires that you change a script block's `type` value to "text/cjs" (from "text/javascript"). I have two problems with this approach. Firstly, as we discussed above, the spec and standards bodies are moving to explicitly de-supporting invalid types. What if sometime soon, the spec says that any element with an unrecognized type should not even be added to the DOM but should be entirely ignored? </p>
<p>Or what if some browser just interprets what the spec currently says to mean that? If I were a browser developer, I could easily argue that the ignoring of such an element (not adding it to the actual DOM) would help improve the page's performance by taking up less memory and having fewer DOM nodes to inspect during DOM traversal/manipulation.</p>
<p>Also, he chose "text/cjs". This assumes future-wise that no MIME-type will ever take the name "text/cjs". Notice that LABjs at least chose a much different value, like "script/cache", which is far less likely to have future collisions. But Steve chose a "text/xxxx" format for the value, which fits closely with how such values currently are assigned, but also makes it more likely that there will be a conflict someday. </p>
<p>Moreover, in HTML5, the type value is now optional, and for performance reasons, I (and most people) now omit that from our markup. ControlJS will require us to go back and add `type` attributes to all our script tags, making the markup <em>slightly</em> larger. That's pretty minor, but it bugs me nonetheless.</p>
<p>Lastly, it is unclear from the code or the documentation what the expected/suggested behavior should be if I have some script tag elements in my markup that are marked-up to have CJS bindings, and other script tags that I leave alone. How will CJS loaded scripts interact (before or after) scripts that are loaded using the browser's native mechanism? If there's some reason I need to have a mixture of CJS and non-CJS script tags in my page, it will make the interpretation of my markup (specifically, the implied execution order of the script elements) a <em>lot</em> more confusing.</p>
<h4>Summary</h4>
<p>This is part 1 of this post. I'm going to make another post soon (part 2) where I shift my focus from ControlJS to HeadJS (and possibly other script loaders).</p>
<p><strong>Again, I apologize to Steve (and to anyone else)</strong> if the tone of this post seems to be overly harsh. But I think it's important that the other side of the coin be put out there for developers to consider as they compare how ControlJS differs from something like LABjs.</p>
<p>Moreover, I reiterate what I've said a dozen times already: <strong>instead of creating more and different script loaders, I think a better use of our time would be to consolidate efforts in getting the browsers and the spec/W3C to give us a reliable native mechanism for managing dynamic script loading.</strong> Since `async=false` is already moving along nicely, I encourage and invite anyone who's interested to join that discussion.</p>
<p>I hope very soon that proper and simple handling of dynamic script loading will be very easy and straightforward, and well-conforming script loaders (which I can say LABjs will certainly be) will eventually be free from a lot of hacky, legacy junk that weighs them down. I call on all other script loaders to join that effort for a better script loading future. (ok, yeah, that was lame. <img src='http://getiblog.2static.it/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> )</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.getify.com/on-script-loaders/feed/</wfw:commentRss>
		<slash:comments>27</slash:comments>
		</item>
		<item>
		<title>Native JavaScript: sync and async</title>
		<link>http://blog.getify.com/native-javascript-sync-async/</link>
		<comments>http://blog.getify.com/native-javascript-sync-async/#comments</comments>
		<pubDate>Tue, 07 Dec 2010 20:47:23 +0000</pubDate>
		<dc:creator>getify</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[async]]></category>
		<category><![CDATA[defer]]></category>
		<category><![CDATA[es5]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[native]]></category>
		<category><![CDATA[operator]]></category>
		<category><![CDATA[promise]]></category>

		<guid isPermaLink="false">http://blog.getify.com/?p=701</guid>
		<description><![CDATA[One of the most powerful parts of JavaScript is that it allows you to code synchronous (serially executing) code along side asynchronous code. But what is powerful also leads to more complication for a variety of common tasks. I&#8217;m going to explore and propose an addition to native JavaScript that I believe will help developers [...]]]></description>
			<content:encoded><![CDATA[<p>One of the most powerful parts of JavaScript is that it allows you to code synchronous (serially executing) code along side asynchronous code. But what is powerful also leads to more complication for a variety of common tasks. I&#8217;m going to explore and propose an addition to native JavaScript that I believe will help developers in negotiating async code tasks within a sync code base.</p>
<p><strong>(note: If you already understand the problems with nesting callbacks for handling async code, and want to just get to the main point and skip over all the boring back-story, <a href="#proposal">read my proposal</a>)</strong></p>
<p>What I&#8217;m going to be talking about is a complex and emerging topic with some specific descriptors attached, like &#8220;promises&#8221; and &#8220;defer&#8221;. It&#8217;s been pushed heavily recently by the server-side JavaScript community (CommonJS), but I think the usefulness of these concepts is just as valid in browser JavaScript. In fact, one major motivator for this exploration is the desire to design a pattern for sync/async coding that is useful in both contexts, so that more code can be written once and re-used.</p>
<p>However, I want to leave aside some of the formalities of the promise/defer conversation (mostly because I am by far not an expert on it) &#8212; I know just enough about them to be dangerous but probably not enough to be useful. I also want to try and separate opinions/preferences about syntax (although part of the goal is shorter/cleaner syntax) aside and talk mostly about the structural/functional needs. It&#8217;s impossible to talk only about the theory, so there will be a syntax I suggest, but I hope that the conversation that develops around my proposal isn&#8217;t side tracked by the &#8220;weeds&#8221; of syntax before we&#8217;ve thoroughly talked about the underlying behaviors.</p>
<p>There&#8217;s a rather long <a href="https://gist.github.com/727232">gist about my explorations of the idea</a> if you&#8217;re interested in seeing the back-story to this post. I think especially interesting is the comment thread with some really good feedback from several people, including the venerable <a href="http://twitter.com/BrendanEich">Brendan Eich</a> himself (hint: he invented JavaScript).</p>
<h3>A callback in your callback so you can callback</h3>
<p>Almost universally, the common pattern in JavaScript for dealing with asynchronous coding is the idea of the callback. That is, taking advantage of the first-class status of functions, passing a reference of a function to an async mechanism, asking for the function to be &#8220;called back&#8221; when the asynchronous process finishes. But most anyone who&#8217;s ever written mid-complexity (or more) code with async functionality has run into several common problems with the callback pattern for async handling. At its most basic definition, what I&#8217;m trying to do here is come up with a better way to handle such tasks. Of course, it goes much deeper than that, but that&#8217;s probably the best mental place to start.</p>
<p>Let&#8217;s first take a look at some example code written in the traditional callback style to illustrate some of these issues:</p>
<pre class="code">
function xhr(url, callback) {
   var x = new XMLHttpRequest();
   x.onreadystatechange = function(){
      if (x.readyState == 4) {
         callback(x.responseText);
      }
   };
   x.open("GET",url);
   x.send();
}

setTimeout(function(){
   xhr("/something.ajax?greeting", function(greeting) {
      xhr("/else.ajax?who&#038;greeting="+greeting, function(who) {
         console.log(greeting+" "+who);
      });
   });
}, 1000);
</pre>
<p>OK, so in this code, we want to wait 1 second (why? who cares!) and then we want to fire off an Ajax request to get some content. Next, we use that content to make a second Ajax request. Finally, once we have both pieces of content fetched, now we print them out to the console.</p>
<p>Firstly, the syntax ugliness of nesting callbacks 3 levels deep illustrates the inefficiency of this pattern. We accept that this is status quo, but in reality, I think this is an example of how the language is not properly (natively) supporting the common programming patterns found in modern usage of the language. We&#8217;re having to hack around with ugly, complicated, and thus harder-to-maintain syntax because that&#8217;s basically our only direct option.</p>
<p>Now, let&#8217;s consider what happens if I want to take that functionality and make it into some sort of general, reusable piece of code. There&#8217;s a few different ways this can be done:</p>
<pre class="code">
function doSomethingCool(url_1, url_2, callback, delay) {
   setTimeout(function(){
      xhr(url_1, function(greeting) {
         xhr(url_2+greeting, function(who){ callback(greeting, who); });
      });
   }, delay);
}

doSomethingCool("/something.ajax?greeting",
   "/else.ajax?who&#038;greeting=",
   function(greeting, who) {
      console.log(greeting+" "+who);
   },
   1000
);
</pre>
<p>Look at the brittleness we&#8217;ve now had to introduce. First, because we&#8217;ve abstracted that a URL (the &#8220;/else.ajax&#8221; one) is something that should be passed in as a parameter, we&#8217;ve now separated the URL passed in with the concatenation of the content received from previous Ajax request. We&#8217;ve created brittleness between code hidden away inside that general function and the calling code. If either of those changes, both pieces of code will have to change. In our example, the code is right next to each other, and not too hard. But what if this code is a method in an object abstracted away in a third-party library. This brittleness is a pattern that will lead to hard-to-maintain code and eventually failure.</p>
<p>Next, notice that we had to change the signature of the callback we pass in, so that it accepts both the `greeting` and `who` parameters, because now our calling code is separate from the context scope (closure) that gave us access to `greeting` in the previous code snippet without it being passed explicitly. And, we have had to use yet another anonymous function inside of `doSomethingCool` to compose the parameters `greeting` and `who` into a single call to our callback. This code will work, but it&#8217;s brittle and it fails the &#8220;sniff&#8221; test &#8212; if it seems to be too complicated, it&#8217;s probably wrong. Is there anything better we can do?</p>
<pre class="code">
function doSomethingSortaCool(url, callback, delay) {
   setTimeout(function(){
      xhr(url, callback);
   }, delay);
}

doSomethingSortaCool("/something.ajax?greeting", function(greeting) {
   xhr("/else.ajax?who&#038;greeting="+greeting, function(who) {
      console.log(greeting+" "+who);
   });
});
</pre>
<p>Meh. This is not getting much better. We removed one layer of the nesting abstraction. But now our calling code is having to take care of the complication instead of our utility. `doSomethingSortaCool()` is a little more general now, but we&#8217;ve just shifted the problem and complexity to the usage code. It seems our nesting is just going to be difficult to deal with.</p>
<p>So, I&#8217;ve been talking thus far about difficulties not only with syntax but also with interaction among components (aka, steps in our asynchronous logic). But let&#8217;s also point out another issue that such a pattern has. This is an issue that is clearly more a concern for server-side JavaScript folks, but it&#8217;s inherent to core JavaScript and thus is something I&#8217;d like to see addressed, regardless of how effective it is in the browser context.</p>
<p>The concern is this: what if `doSomethingCool()` is a function we did not write and do not control? What if we are linking to a third-party library that we can&#8217;t fully &#8220;trust&#8221; to always behave as it should? The misbehavior could be intentional/malicious, or it could simply be poorly implemented. But in either case, by calling it, and specifically passing to it a reference to one of our functions, we are <em>trusting</em> that function to execute our function for us at the appropriate time. Misbehavior could be calling our callback too early, or too late, or more than once, or never, or passing not enough parameters, or passing the wrong data, etc.</p>
<p>Not only are we &#8220;trusting&#8221; that function to behave properly, but we also have basically very little way to directly assert and enforce that proper behavior. We can go to great lengths in our callback&#8217;s scope to keep track of when and how it is called, making sure it&#8217;s only ever called once, and that it&#8217;s passed proper data. But that&#8217;s a crazy amount of work to do for <strong>every single callback function we ever define</strong>. Clearly, this code is begging for a more robust system to negotiate these problems for us.</p>
<p>Let&#8217;s step back a little more general now:</p>
<pre class="code">
X(..., Y);
</pre>
<p>`X` is possibly an asynchronous function, meaning it may not finish right away (but it might!). But we don&#8217;t want `Y` to finish until after `X` is done. Moreover, we want `Y` to be notified of the eventual result of `X` when it is complete.</p>
<p>We pass `Y` to `X` and expect that `X` will execute it for us. Not only that, but we expect that X will make sure to pass the right parameters to `Y`. What if we actually need to specify some of the parameters for `Y`? We can pass all those parameters to `X` and ask it to add them to the call correctly. Or we can &#8220;curry&#8221; `Y` into a partially applied function, and pass that intermediate function to `X` instead. Currying is a standard pattern, but it&#8217;s a little advanced, and it involves some complexities that may be prohibitive. It also uses implicit anonymous function wrapper(s), which hampers our code&#8217;s efficiency the more layers of wrapping we have to involve.</p>
<pre class="code">
X(..., function(){ Y(..., Z); });
</pre>
<p>Here, we&#8217;re doing the same thing, but now we&#8217;re passing in a hard-coded function that will call `Y` for us. However, we&#8217;re passing <em>that</em> function to `X`, so we&#8217;re still trusting `X` to behave properly. Moreover, we&#8217;ve created brittleness because this callback must call `Y`, which must pass in `Z`. We saw above the complexities if we want to generalize those connections. Lastly, we&#8217;re <em>also</em> now trusting that `Y` will properly behave with respect to `Z`. If `X` and `Y` are third-party, and only our `Z` we control, we&#8217;ve doubled the ways that our code may assume proper behavior and fail because we&#8217;re not certain that it will indeed do what we want.</p>
<p>One final wrinkle: we often need to define both what happens if the asynchronous code `X` finishes successfully, and what happens if it fails in some way. So, with the callback paradigm, now we&#8217;re passing twice as many functions to every layer of abstraction, and again, we&#8217;re relying even more so on the potentially untrusted code to make sure one or the other (but not both!) of our callbacks are called under the appropriate circumstances.</p>
<p><strong>The problem is that we can&#8217;t &#8220;trust&#8221; (in the sense we&#8217;ve been discussing) code we don&#8217;t control</strong>, so <em>we</em> (that is, our direct code) need a way to be in control all of the execution, not the third-party code. Also, messaging between the async steps can get really complex quickly when nesting is involved. Lastly, parameter passing to subsequent steps must either be hard-coded or we must jump through lots of hoops to get them passed properly.</p>
<pre class="code">
X(...);
Y(...);
Z(...);
</pre>
<p>It would be ideal if our code could be written like this, and `X`, `Y`, and `Z` could all be asynchronous and the order would be preserved. As it stands, this is not possible. If any of those functions defers its completion by calling an async call, processing will continue, and thus order of completion will not be maintained.</p>
<p>&#8220;Continuations&#8221; are a programming concept where the code execution can suspend itself after `X(&#8230;)` is called, and the rest of the program can be &#8220;continued&#8221; later when `X` finishes, etc. One such syntax might look like:</p>
<pre class="code">
X(...); yield;
Y(...); yield;
Z(...); yield;
</pre>
<p>I&#8217;m not suggesting this is how we should deal with our issue. But it at least is informative to look at the other ways these problems have been tackled in the past.</p>
<p>Put simply, we want/need a linear sequence of function calls. We need those functions to execute in order, even if one or all of them are asynchronous in nature. We need those functions to be able to cascade/propagate their results down the sequence, so that step 2 knows what the result of step 1 was (in case it needs it), etc. (btw, the &#8220;message passing&#8221; should not rely on shared state side-effects.) And we need a way to express what happens if any step in our sequence of function calls fails to fulfill its success path.</p>
<h3>APIs</h3>
<p>I hope I&#8217;ve now illustrated the issues that first-order function reference callbacks fall short of adequately addressing those needs. I&#8217;m not by any means the first person to articulate such issues or try to find solutions to these shortcomings. There are a number of proposals in the CommonJS community for handling &#8220;promises&#8221;. Dojo has a &#8220;deferred&#8221; utility. And there are many others.</p>
<p>I&#8217;ve even experimented with a chainable API syntax shim for handling them. For instance:</p>
<pre class="code">
function delay(time) {
   var p = new Promise();
   setTimeout(function(){ p.fulfill(); }, time);
   return p.deferred;
}
function xhr(url) {
   var p = new Promise(),
         x = new XMLHttpRequest()
   ;
   x.onreadystatechange = function(){
      if (x.readyState == 4) {
         p.fulfill(x.responseText);
      }
   };
   x.open("GET",url);
   x.send();
   return p.deferred;
}

delay(1000)
.then(function(){
   return xhr("/something.ajax?greeting");
})
.then(function(P){
   return xhr("/else.ajax?who&#038;greeting="+P.value)
   .then(function(P2){ return [P.value, P2.value]; });
})
.then(function(P){
   console.log(P.value[0]+" "+P.value[1]);
});
</pre>
<p>So, notice how this (really naive and simple) experiment into promises that I did is trying to address some of the concerns. First and foremost, the `Promise` system (sort of a neutral trustable party) acts as a &#8220;proxy&#8221; of sorts between the various steps of this chain. I pass functions to the `Promise` mechanism by calling the `.then(&#8230;)` chained method of the object (aka &#8220;deferred&#8221;) that each of my functions returns. I&#8217;m not passing my functions to some untrusted third-party system, I&#8217;m passing them to a trusted neutral party. The `Promise` system only has one way that a function can signal that it&#8217;s finished: `fulfill(&#8230;)`. </p>
<p>This is guaranteed (by the `Promise` mechanism) to be callable once and only once. And `fulfill(&#8230;)` can take a &#8220;value&#8221; (aka, &#8220;message&#8221;) that it will pass along to the next step in the chain. Lastly, this syntax (while a little clunky itself) does address at least some of the awkwardness of nesting callbacks, parameter hard-coding, etc.</p>
<p>The point of me bringing this up is not to suggest that it&#8217;s the right way to deal with these problems. Most people seem to favor an alternate (not really chainable) syntax often called `when` syntax. It might look like this:</p>
<pre class="code">
when(X, Y, Z);
</pre>
<p>That means, execute `X`. If successful, do `Y`, otherwise do `Z`. While chainability of this particular syntax is not straightforward (and is likely achieved with&#8230; nesting when&#8217;s), one great thing it does is address the concern that X shouldn&#8217;t have to execute Y or Z (or even <strong>know</strong> about them, for that matter). This `when(&#8230;)` is similar to my `Promise` experiment &#8212; a neutral party mechanism to negotiate promise deferral.<br />
<a name="proposal"></a></p>
<h3>A modest (native) proposal</h3>
<p>While there are many proposals for handling promises, and some of them are even eventually hoping to be a candidate for inclusion in the language, I&#8217;d say they are all mostly API focused. I believe my new proposal (while it has some API to it) is more focused at a lower level than API, and I hope is easier to integrate natively into the language.</p>
<p>Revisiting the generic example from above:</p>
<pre class="code">
X(...) ,
Y(...) ,
Z(...);
</pre>
<p>Notice, I&#8217;ve used a &#8220;,&#8221; between `X` and `Y` and between `Y` and `Z`. This should not be interpreted to mean I&#8217;m suggesting that syntax. I just want to illustrate the general concept that I want to be able to easily specify a &#8220;chain&#8221; of 3 expressions (in this case, async function calls), and I want for those 3 to evaluate in order, even if the processing needs to suspend because of async deferral. I could just as easily list the example like this, and mean basically the same thing:</p>
<pre class="code">
????  X(...)  ????  Y(...)  ????  Z(...)  ????
</pre>
<h4>Execution/Processing Model</h4>
<p>Further, let me state, in contrast to the formal &#8220;yield/continuation&#8221; model discussed above, I don&#8217;t think that `X` deferring itself means that the entire rest of the program needs to be yielded. In this case, I&#8217;ve arranged these 3 function calls into a single statement. <strong>So, the &#8220;yield/continuation&#8221; behavior would be localized only to the single statement</strong>. The statement will always be executed part-by-part, from left-to-right.</p>
<p>If the statement at any point suspends itself (defers completion), program execution would then continue immediately at the next statement. When the &#8220;suspended&#8221; statement is ready to resume, it will wait for the next &#8220;turn&#8221; available (in the exact same way in JS as any other async code waiting to execute), and will then continue on with execution of the next part of the statement. A statement can be &#8220;suspended&#8221; and &#8220;resumed&#8221; back and forth as many times as necessary.</p>
<p>The &#8220;suspension&#8221; is always controlled by the function calls in the statement (ie, yielding, not pre-emptive interruption).</p>
<p>The statement doesn&#8217;t get any special behavior with respect to any references to surrounding scoped variables. Each part of the statement will be executed at immediate-point-in-time taking into account whatever the current scope state is. There&#8217;s no suggestion that any type of state insulation where parts of the statement are protected from effects from other parts of the statement or from the rest of the program. In this respect, the async completing code behaves in pretty much the same way as a callback function that is executed later &#8212; it knows about references to variables, but it will use their current state when it executes that part of the statement.</p>
<p>Each part of the statement that is a function call which suspends (aka &#8220;defers&#8221;) its own completion, when it resumes/finishes, it will then be able to signal to the next part of the statement a &#8220;message&#8221; as the final result of the function call. Each part of the statement that is a function call which immediately follows an async part will be able to receive the &#8220;message&#8221; from the previous part, separate from and in addition to any explicit parameters to the function call itself. This &#8220;message passing&#8221; mechanism must not rely on shared state variable side-effects, but must instead be intrinsic to the statement handling mechanism.</p>
<p>The statement of this nature has 2 or more parts to it, but no part actually has to be a function call, or even if a part is a function call, that function call doesn&#8217;t have to suspend itself but can instead finish completely synchronously. The parts of a statement that are not function calls can be any kind of expression, but not other statements (like control structures, return, var, etc). These non-function-call parts (general expressions) cannot suspend themselves, and must therefore always be evaluated/executed synchronously immediately. Only a function call (even an executing function expression) may suspend itself for the purposes of async.</p>
<pre class="code">
???? X()  ????  (Y = 10)  ????  Z() ????
            // `Y = 10` would be an immediately fulfilled promise expression
            // that moved execution onto the next expression in the statement.
</pre>
<p>As is true for the rest of JavaScript (which does not yet have { } block level scope), the only way to contain multiple statements inside a single part of the main  statement is to wrap them in an inline function and execute that function. There are no special semantics or rules for each individual part of the main statement, except that each of them must be a valid expression.</p>
<p>Each time a function is called that may suspend itself, there must be a way to specify in the statement both a success path (if the function finishes as expected) and a failure path (if the function completes but not with expected results).</p>
<h4>Syntax</h4>
<p>Let me get specific about my idea for syntax based on the context described above. But I won&#8217;t spend too much time on it, because the syntax is less important than the execution/processing model.</p>
<p>I propose that the parts of the statement in question be separated by a new infix operator: @. The @ operator is like the , operator in that it evaluates multiple expressions one at a time, but it has the special behavior that it understands when a function suspends/defers itself, and suspends evaluation of the rest of the statement until that part completes.</p>
<p>As stated above, each operand of the @ operator can be a function call, but may just be a general expression. If an operand is a function call, and it suspends/defers its completion, the @ operator will wait to continue. Otherwise, immediate resolution will proceed through the statement, expression by expression, left to right.</p>
<p>The @ operator also has a syntax similar to the ?: ternary operator which expresses the success/failure conditional paths. Only one of the two expression clauses will be executed, depending on how the function chooses to resolve itself (fulfillment or failure).</p>
<p>Lastly, the message passing described above is implicitly handled by the @ operator mechanism, exposed only to function calls in the statement.</p>
<p>Let&#8217;s revisit an earlier example and see how the @ operator would be used:</p>
<pre class="code">
function delay(time) {
   var p = promise;  // `promise` is now a special auto variable
                     // like `arguments` or `this`
   setTimeout(function(){ p.fulfill(); }, time);
   p.defer(); // used to flag this function as deferring/suspending
              // its completion to be async
}
function xhr(url) {
   var p = promise,
         args = p.messages || [],
         x = new XMLHttpRequest()
   ;
   x.onreadystatechange = function(){
      if (x.readyState == 4) {
         args.push(x.responseText);
         p.fulfill.apply(null,args);
      }
   };
   if (p.messages) url += p.messages[0];
   x.open("GET",url);
   x.send();

   p.defer();
}

delay(1000) @
xhr("/something.ajax?greeting") @
xhr("/else.ajax?who&#038;greeting=") @
(function() {
   console.log(promise.messages[0]+" "+promise.messages[1]);
})();
</pre>
<p>As you can see, I chain 4 function calls together with @ in between, the first 3 of which are async and deferred. As discussed in the processing model above, and also in the required/desired behaviors for an async/promise/defer system, this syntax accomplishes all those basic goals.</p>
<p>The simple &#8220;API&#8221; portion of my proposal is how you interact with the &#8220;promise&#8221; mechanism from inside of any function. There is a native auto variable `promise` (similar to `arguments` or `this`) which represents that function call&#8217;s promise. The `promise` object has a `fulfill(&#8230;)` method and a `fail(&#8230;)` method, for (not surprisingly) fulfilling the promise or failing it. Lastly, you opt into deferring a function&#8217;s completion by calling `defer()` on its promise object.</p>
<p>Both the API and the operator are my basic first pass proposal, and are open to input/adjustment.</p>
<h3>Summary</h3>
<p>I&#8217;m not trying to solve all of the issues that a language like JavaScript has with dealing with complex async/chained logic through promises/defers. I&#8217;m not suggesting that noone will ever have to use a promise/defer &#8220;lib&#8221; of some sort for the more complex negotiation tasks. I&#8217;m not suggesting that @ will be the cure all.</p>
<p>What I am suggesting is that the best first step to take in helping deal with sync/async negotiation in JavaScript is for there to be a small, narrowly defined, natively implemented mechanism (in my idea, as a special operator), which will serve as a building block for more complex usage, and will simultaneously provide very streamlined and simple syntax for a wide array of common sync/async tasks (like event binding, as seen in the <a href="https://gist.github.com/727232#file_ex4:click_event_handlers_as_promises">original gist exploration</a>).</p>
<p>I genuinely want to avoid some of the syntactic disagreements that have held back promise/defer API implementations by stripping down a significant part of it to a simple chainable infix operator. That doesn&#8217;t mean there&#8217;s no API, nor does it mean the function API I&#8217;ve proposed is correct. It just means that we need something efficient and native in JavaScript sooner, rather than later, to being dealing with sync vs. async issues. I think my proposal has some merit in the respect of being a productive step forward (and one of many necessary steps we must take as a language).</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.getify.com/native-javascript-sync-async/feed/</wfw:commentRss>
		<slash:comments>9</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 07:22:56 -->
