<?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>NIX/WIN/WEB &#187; JavaScript</title>
	<atom:link href="http://www.formboss.net/blog/category/javascript/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.formboss.net/blog</link>
	<description>Modern Web Application Development</description>
	<lastBuildDate>Thu, 02 Feb 2012 18:43:36 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>jQuery vs. Prototype – Part 2</title>
		<link>http://www.formboss.net/blog/2011/10/jquery-vs-prototype-%e2%80%93-part-2/</link>
		<comments>http://www.formboss.net/blog/2011/10/jquery-vs-prototype-%e2%80%93-part-2/#comments</comments>
		<pubDate>Sun, 23 Oct 2011 20:23:12 +0000</pubDate>
		<dc:creator>grdinic</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[Prototype JS]]></category>

		<guid isPermaLink="false">http://www.formboss.net/blog/?p=1480</guid>
		<description><![CDATA[In the first post of this series we looked at the common misconception of jQuery being the &#8220;lightweight&#8221; JavaScript library. In this post we&#8217;ll leave the sidelines and jump right into some real-world scenarios. I want to see what makes jQuery tick by comparing it to my beloved Prototype. A quick note as we get [...]]]></description>
			<content:encoded><![CDATA[<p>In the first post of this series we looked at the common misconception of jQuery being the &#8220;lightweight&#8221; JavaScript library. In this post we&#8217;ll leave the sidelines and jump right into some real-world scenarios. I want to see what makes jQuery tick by comparing it to my beloved Prototype.</p>
<p><span id="more-1480"></span><br />
<em>A quick note as we get started: I&#8217;ve never coded in jQuery before, so my apologies ahead of time if I miss something obvious!</em></p>
<h2>A Button Clicking Example</h2>
<p>In this first example let&#8217;s see what a typical event handler for a button click looks like when following the design pattern of separating design from implementation: </p>
<p><strong>Prototype:</strong></p>
<pre class="brush: jscript; title: ; notranslate">
&lt;!DOCTYPE html&gt;
&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot;&gt;
&lt;head&gt;
&lt;script src=&quot;prototype.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=utf-8&quot; /&gt;
&lt;title&gt;Prototype&lt;/title&gt;

&lt;script type=&quot;text/javascript&quot;&gt;

// bind each button
document.observe('dom:loaded', function(){

	syntax = 'quick';

	if(syntax == 'quick'){
		// quick syntax
		$$('.dynamic-element-wrapper &gt; INPUT').invoke('observe', 'click', buttonClicked);
	}

	if(syntax == 'verbose'){
		// verbose
		$$('.dynamic-element-wrapper &gt; INPUT').map(function(t){
			t.observe('click', buttonClicked);
		});
	}

});

function buttonClicked(e){
	$('console').update(e.element().id + ' Clicked');
};

&lt;/script&gt;

&lt;/head&gt;

&lt;body&gt;

&lt;div class=&quot;dynamic-element-wrapper&quot;&gt;
	&lt;input type=&quot;button&quot; id=&quot;button-1&quot; name=&quot;button-1&quot; value=&quot;Button 1 - Click Me&quot; /&gt;
    &lt;input type=&quot;button&quot; id=&quot;button-2&quot; name=&quot;button-2&quot; value=&quot;Button 2 - Click Me&quot; /&gt;
&lt;/div&gt;

&lt;div style=&quot;clear:both;&quot; id=&quot;console&quot;&gt;&lt;/div&gt;

&lt;/body&gt;
&lt;/html&gt;
</pre>
<p><strong>jQuery</strong></p>
<pre class="brush: jscript; title: ; notranslate">
$(document).ready(function() {

	syntax = 'verbose';

	if(syntax == 'quick'){
		$('.dynamic-element-wrapper &gt; INPUT').click(buttonClicked);
	}

	if(syntax == 'verbose'){
		$('.dynamic-element-wrapper &gt; INPUT').bind('click', buttonClicked);
	}

});

function buttonClicked(e){
	$('#console').html(e.target.id + ' Clicked');
};
</pre>
<p><em>Please note that as the HTML doesn&#8217;t change the jQuery code sample is limited to just the SCRIPT block.</em></p>
<p><strong>So a couple items of note:</strong></p>
<p>As a long-time Prototype guy jQuery&#8217;s automatic array return when using $() sits in stark contrast to Prototype&#8217;s use of $$(). I have to admit I&#8217;m torn on this one, as in a way the jQuery way makes more sense. The selector and knowledge of the document, combined with the function our event listeners call should be all that&#8217;s needed from a selector. In practical terms then differentiating between $() and $$() is admittedly more work without a huge gain in readability. </p>
<p>That aside, in Prototype we also get a bit more syntax heavy having to resort to <strong>.invoke()</strong> or <strong>.map()</strong>, whereas jQuery&#8217;s <strong>.click()</strong> makes short work of the job &#8212; providing a quick and concise way to perform such a common task is a huge win.  </p>
<p>On the event processing side our <strong>buttonClicked()</strong> call is very similar. Once again jQuery&#8217;s love of shortcuts impresses me. <strong>.html()</strong> for getting <em>and </em>setting text is quite nice, and from what I can see, is duplicated via <strong>.val()</strong> of the form field side. </p>
<h2>The this Reference Binding Issue</h2>
<p>So here comes the main event. The example above in terms of design pattern is going to be just fine for most projects. Our design code is free from implementation code and when we click the element we get the info we need &#8212; everything just works. </p>
<p>But what happens when we follow a slightly more complex design pattern? Many times allowing UI implementation code to hover in the global script scope is perfectly acceptable. But their are times, either by virtue of space or code cleanliness, that wrapping our event code into objects is desirable or required. </p>
<p>An example of doing so in <strong>Prototype </strong>looks like this:</p>
<pre class="brush: jscript; title: ; notranslate">
var buttonFactory = {

	_limit: 10,
	_secure: true,

	bindObjects: function(){
		$$('.dynamic-element-wrapper &gt; INPUT').invoke('observe', 'click', this.buttonClicked);
	},

	buttonClicked: function(e){
		$('console').update(e.element().id + ' was clicked. ' + 'The limit value = ' + this._limit);
	}

};

// bind each button
document.observe('dom:loaded', function(){
	buttonFactory.bindObjects();

});
</pre>
<p>As you can see instead of binding our event listeners in the global scope we issue a simple call to <strong>buttonFactory.bindObjects()</strong>. If this was a much larger project it&#8217;s not hard to see why this would be a great way to work. Our <strong>document.observe</strong> code would simply be a series of calls to code that initialize other parts of the UI. The initialization code would then perform all sorts of long-winded tasks while leaving our <strong>document.observe</strong> call far from the down and dirty details. </p>
<p>But all&#8217;s not well. When coding this way &#8212; if not just to save space but to also create more complex event handling logic &#8212; we would expect that our <strong>buttonClicked()</strong> code would handle the reference to <strong>this._limit</strong> but it doesn&#8217;t. We&#8217;ll get this when we click a button:</p>
<pre class="brush: plain; title: ; notranslate">button-2 Was Clicked. The limit value = undefined</pre>
<p>That&#8217;s not at all what we want. You&#8217;d think <strong>this._limt</strong> should return with a value of 10 but it doesn&#8217;t. Why? </p>
<p>The problem is when we bound our event listener the <em>this </em>reference wasn&#8217;t part of the process. This means when we trigger a click event the <em>this </em>refers to the <strong>event object</strong>, not the buttons original parent object (buttonFactory). </p>
<p>Prototype has a solution for this via a call to <strong>bindAsEventListener()</strong>. <strong>bindAsEventListener()</strong> takes the object we wish to use as the <em>this </em>reference when invoked. To implement this fix in our example code we&#8217;d change our <strong>bindObjects()</strong> call to:</p>
<pre class="brush: jscript; title: ; notranslate">
//
//
$$('.dynamic-element-wrapper &gt; INPUT').invoke('observe', 'click', this.buttonClicked.bindAsEventListener(this));
//
//
</pre>
<p>Now when we run our code it returns the following when a button&#8217;s clicked:</p>
<pre class="brush: plain; title: ; notranslate">button-1 was clicked. The limit value = 10</pre>
<p>That&#8217;s more like it. Sure this is a synthetic example, but it&#8217;s absolutely essential to creating <em>portable </em>code. </p>
<p>Portable is the key word here, as yes, we could just do this to our <strong>buttonClicked() </strong>call:</p>
<pre class="brush: jscript; title: ; notranslate">
//
//
$('console').update(e.element().id + ' was clicked. ' + 'The limit value = ' + buttonFactory._limit);
//
//
</pre>
<p>But this would be in bad form in my opinion, as now we&#8217;re making all sorts of assumptions of how this object will be consumed. </p>
<p>So the point is Prototype gives us a sleek, consistent way of holding objects together in event-driven code. </p>
<p>How does jQuery solve this issue?</p>
<p><strong>jQuery</strong></p>
<pre class="brush: jscript; title: ; notranslate">
var buttonFactory = {

	_limit: 10,
	_secure: true,

	bindObjects: function(){
		$('.dynamic-element-wrapper &gt; INPUT').bind('click', this, this.buttonClicked);
	},

	buttonClicked: function(e){
		$('#console').html(e.target.id + ' Clicked' + 'The limit value = ' + e.data._limit);
	}

};

$(document).ready(function() {
	buttonFactory.bindObjects();
});
</pre>
<p>The <a href="http://api.jquery.com/bind/" target="_blank">method signature</a> of .bind() as we&#8217;re using it is:</p>
<pre class="brush: plain; title: ; notranslate">.bind( eventType [, eventData], handler(eventObject) )</pre>
<p>Thus, my solution is to simply pass our object reference as the <strong>eventData </strong>argument. We then pick up on the value via the <strong>event.data </strong>object in <strong>buttonClicked()</strong> and away we go. </p>
<p>Seems simple enough but again I do not have&#8230;well&#8230;<em>any </em>jQuery experience, so I would not be surprised is this is wrong in terms of implementation. What I <em>can </em>say though is it works just fine, and once again the syntax is pretty slick. For Prototype adding bindAsEventListener() is every bit as cumbersome as <strong>document.getElementById()</strong> if you catch my drift&#8230;</p>
<p>I say it works fine as for my part I did issue a test call of:</p>
<pre class="brush: jscript; title: ; notranslate">e.data._limit = 20;</pre>
<p> under the <strong>#console</strong> update call and sure enough, the <strong>buttonFactory </strong>object was updated accordingly. From this we can tell <em>this </em>is passed as a reference, which means for my money this is an acceptable, working solution. </p>
<p>For the sake of completeness it appears we can also use <a href="http://api.jquery.com/jQuery.proxy/" target="_blank">.proxy()</a>. </p>
<p>When used our code changes to:</p>
<pre class="brush: jscript; title: ; notranslate">
var buttonFactory = {

	_limit: 10,
	_secure: true,

	bindObjects: function(){
		var bProxy = $.proxy(this.buttonClicked, this);
		$('.dynamic-element-wrapper &gt; INPUT').bind('click', bProxy);

	},

	buttonClicked: function(e){
		$('#console').html(e.target.id + ' Clicked' + 'The limit value = ' + this._limit);
		e.data._limit = 20;
	}

};

$(document).ready(function() {
	buttonFactory.bindObjects();
});
</pre>
<p>I&#8217;m not entirely sold on this method as now we&#8217;re once again in the mode of hand-wrangling specific behavior from our objects. It&#8217;s nice to know it can be done, however.</p>
<h2>Conclusion</h2>
<p>The title of this post has a <em>vs.</em> in it so who wins this round? Somewhat unsurprisingly I think it&#8217;s a draw, though if I had to pick I&#8217;d say jQuery. jQuery&#8217;s ability to pass <em>this </em>as an event parameter and it still works is fine by me and easier to code, and considering we can just as easily wrap <em>this </em>into a larger structure is better still.</p>
<p>Of course I&#8217;m ready and willing to have any and all ignorance corrected, so if you&#8217;ve seen something that&#8217;s not right with my solution(s) please let me know! </p>
<p>The bottom line is jQuery has some real time savers in its bucket of tricks; the fact that $() returns arrays is worth the price of admission alone.</p>
<p>Color me continually intrigued.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.formboss.net/blog/2011/10/jquery-vs-prototype-%e2%80%93-part-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>jQuery vs. Prototype &#8211; Part 1</title>
		<link>http://www.formboss.net/blog/2011/10/jquery-vs-prototype-part-1/</link>
		<comments>http://www.formboss.net/blog/2011/10/jquery-vs-prototype-part-1/#comments</comments>
		<pubDate>Sat, 22 Oct 2011 18:50:27 +0000</pubDate>
		<dc:creator>grdinic</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[Prototype JS]]></category>

		<guid isPermaLink="false">http://www.formboss.net/blog/?p=1449</guid>
		<description><![CDATA[One of the hottest JavaScript libraries on the planet is jQuery. It&#8217;s opened up a world of web developers to functionality and ease they would not otherwise know, and has done so without stepping on anyone toes. Their are hundreds of great extensions for it made by a first-rate community that&#8217;s almost always helpful and [...]]]></description>
			<content:encoded><![CDATA[<p>One of the <a title="http://appendto" href="http://appendto.com/jquery-overtakes-flash" target="_blank">hottest</a> JavaScript <a title="codeclimber" href="http://codeclimber.net.nz/archive/2009/06/22/ajax-survey-2009-jquery-and-ms-ajax-are-almost-tied.aspx" target="_blank">libraries</a> on the planet is jQuery. It&#8217;s opened up a world of web developers to functionality and ease they would not otherwise know, and has done so without <a title="noConflict()" href="http://api.jquery.com/jQuery.noConflict/" target="_blank">stepping on anyone toes</a>. Their are hundreds of great extensions for it made by a first-rate community that&#8217;s almost always helpful and supportive. When it comes to getting a job I&#8217;d say jQuery knowledge is <a title="Stack Overflow" href="http://stackoverflow.com/questions/932967/do-javascript-developers-need-to-know-jquery" target="_blank">almost becoming requirement</a>, if not right away then as part of your integration into that job.</p>
<p>Prototype JS is&#8230;well&#8230;it&#8217;s another JavaScript library. But it&#8217;s the library I know and <em>love</em>. It&#8217;s what drives FormBoss and while not as exciting or popular as jQuery, I swear its day <em>will </em>come (again). Their are many reasons for this belief, but the first is due to what I believe is a fundamental misconception about jQuery vs. other libraries &#8212; its payload size.</p>
<p>In this first of a multi-part series we&#8217;ll take a look at the physical delivery size of each library. In the next post well dive into practical programming. First though, a bit of background.</p>
<p><span id="more-1449"></span></p>
<h2>Background</h2>
<p>As a professional Web Developer I had a decision to make in mid-2008 as to what JavaScript library I would use for FormBoss. At that time I was looking for a library that fixed JavaScript&#8217;s core issues and had good AJAX support. (<em>Little did I know that while AJAX support was important, far more relevant would be DOM handling and event binding, but more on that latter</em>).</p>
<p>I checked a few libraries starting with Yahoo&#8217;s <a title="YUI" href="http://developer.yahoo.com/yui/" target="_blank"><em>YUI </em></a>and <a title="Dojo" href="http://dojotoolkit.org/" target="_blank"><em>Dojo</em></a>. Forget it. Far more complex than I needed, they seemed to make even simple tasks difficult (<em>disclaimer: I haven&#8217;t looked into these libraries for some time now, they may be better, or perhaps my initial impressions were wrong!</em>).</p>
<p>What I really wanted was a library like PHP. Provide a solid foundation that was <em>not </em>unto itself a framework. All I wanted was something that extends and smooths over vanilla JavaScript but also provides glue functions for doing more advanced stuff.</p>
<p>It wasn&#8217;t long before I narrowed my decision down to Prototype and jQuery (at <em> versions 1.6.0.3 and at 1.2.6., respectively)</em>. Both seemed strong &#8211; jQuery on the count of its small size and simplicity, Prototype because of its more robust feature-set and AJAX support (<em>again though DOM traversal and event binding played no part in this process, but would become crucial later on</em>).</p>
<p>In the end I went with Prototype for a simple reason &#8212; it seemed more &#8220;complete&#8221; in terms of a programming construct. jQuery, always bragging about how small it was seemed almost <em>too </em>small, too limiting. I wasn&#8217;t looking for flash but utility, and Prototype fit the mold. For the most part I haven&#8217;t regretted this decision one bit&#8211;in the intervening years Prototype has been wonderful to me and always delights. In places where it needed improvement like upgrading to the Selectors API it&#8217;s done so in a reasonable time-frame, and for just about everything else, such as animation and event binding, it&#8217;s never let me down.</p>
<p>But always in the back of my mind has been jQuery, a nagging sense that I&#8217;m missing something. Why has it gotten so popular and does this mean I should be using it too?</p>
<h2>Modern jQuery &#8211; The Popular Place To be</h2>
<p>The base answer to our question of <em>why so popular</em> can be found right at the top of the jQuery <a title="jQuery" href="http://jquery.com/" target="_blank">home page</a>:</p>
<p><a rel="attachment wp-att-1450" href="http://www.formboss.net/blog/2011/10/jquery-vs-prototype-part-1/get-jquery/"><img class="alignnone size-full wp-image-1450" title="get-jquery" src="http://www.formboss.net/blog/wp-content/uploads/2011/10/get-jquery.png" alt="" width="295" height="218" /></a></p>
<p>Compare that with <a title="Prototype JS" href="http://www.prototypejs.org/" target="_blank">Prototype</a>:</p>
<p><a rel="attachment wp-att-1451" href="http://www.formboss.net/blog/2011/10/jquery-vs-prototype-part-1/get-prototype/"><img class="alignnone size-full wp-image-1451" title="get-prototype" src="http://www.formboss.net/blog/wp-content/uploads/2011/10/get-prototype.png" alt="" width="260" height="68" /></a></p>
<p>Ugh. It&#8217;s no wonder jQuery has more hype &#8212; seriously &#8212; by download link alone jQuery simply looks cooler and more advanced.</p>
<p>But it&#8217;s not just that&#8230;well not entirely : )</p>
<p>When you look at the jQuery download options you see that magic value: <strong>31KB</strong>.</p>
<p>How brilliant can they be? Think about all of those large newspaper, e-commerce, and other highly trafficked sites. Bandwidth is money, and when it comes time to tell your boss you need to add more weight to a site it had better be as little as possible <em>and </em>worth it. More importantly, even as recently as 2009 <a title="FCC Broadband Adoption" href="http://online.wsj.com/public/resources/documents/FCCSurvey.pdf" target="_blank">broadband adoption</a> in America was still only 67%. Sure that number continuies to rise but now consider our rising mobile Internet use. Truly two steps forward and one step back.</p>
<p>The point is size still matters, and Prototype&#8217;s stubborn lack of a minified version and frankly boring site and download page mean of course jQuery&#8217;s flashy site will draw more users in, both from a aesthetic and practical standpoint.</p>
<h2>In Reality&#8230;</h2>
<p>But of course we&#8217;re developers so we go deeper than that, and in preparation for this post I was&#8211;admittedly&#8211;floored by a simple test:</p>
<p><a rel="attachment wp-att-1452" href="http://www.formboss.net/blog/2011/10/jquery-vs-prototype-part-1/relative-sizes/"><img class="alignnone size-full wp-image-1452" title="relative-sizes" src="http://www.formboss.net/blog/wp-content/uploads/2011/10/relative-sizes.png" alt="" width="277" height="314" /></a></p>
<p>Had you asked me just five minutes ago I would have said &#8220;<em>Of course</em> jQuery is smaller, everyone knows that!&#8221;.</p>
<p>As of 1.6.4 jQuery has actually grown larger than Prototype in terms of raw source , 6084 lines vs. 9048 (and almost twice as large in terms of raw source code size in KB). More importantly though is while the minified version of Prototype is still larger, the minified + gzipped versions are <em>identical</em>. More importantly still: the minified jQuery is not 32KB but ~90KB. This is important because the jQuery website makes you feel like you&#8217;ll be getting all of that functionality for 32kb, but <em>only </em>if your server is gzipping content. The simple fact is almost all shared hosting plans won&#8217;t be doing do, which means your 32KB is actually closer to 90KB. And no, it&#8217;s not just the smaller plans, it happens with the big boys as well:</p>
<p><a title="Nordstrom" href="http://shop.nordstrom.com/" target="_blank">http://shop.nordstrom.com/</a></p>
<p>Run a Firebug NET session on that site and you&#8217;ll see what we&#8217;re about to cover below. They use a minified but not gzipped version of jQuery (version 1.5.1), which means payload size is 51KB.</p>
<p>In that light it&#8217;s instructive to see what happens with no server size gzipping with the latest versions of each library:</p>
<p><strong>Prototype.js</strong></p>
<p><a rel="attachment wp-att-1453" href="http://www.formboss.net/blog/2011/10/jquery-vs-prototype-part-1/prototype-js-server-no-gzip/"><img class="alignnone size-full wp-image-1453" title="prototype-js-server-no-gzip" src="http://www.formboss.net/blog/wp-content/uploads/2011/10/prototype-js-server-no-gzip.png" alt="" width="796" height="140" /></a></p>
<p><strong>jQuery</strong></p>
<p><a rel="attachment wp-att-1454" href="http://www.formboss.net/blog/2011/10/jquery-vs-prototype-part-1/jquery-js-server-no-gzip/"><img class="alignnone size-full wp-image-1454" title="jquery-js-server-no-gzip" src="http://www.formboss.net/blog/wp-content/uploads/2011/10/jquery-js-server-no-gzip.png" alt="" width="796" height="140" /></a></p>
<p>Here we can can very little server time spent on the requests, but with jQuery&#8217;s minified version definitely being smaller. Again though, the 32KB shown on the jQuery website, while true as it clearly states &#8220;Gzipped&#8221;, is not what we get without the server actually gzipping, as we would expect.</p>
<p>However, as soon as we enabling server size gzipping [via Apache&#8217;s mod_deflate using:</p>
<pre class="brush: plain; title: ; notranslate">LoadModule deflate_module modules/mod_deflate.so</pre>
<p>we get:</p>
<p><strong>Prototype</strong></p>
<p><a rel="attachment wp-att-1455" href="http://www.formboss.net/blog/2011/10/jquery-vs-prototype-part-1/prototype-js-server-gzip/"><img class="alignnone size-full wp-image-1455" title="prototype-js-server-gzip" src="http://www.formboss.net/blog/wp-content/uploads/2011/10/prototype-js-server-gzip.png" alt="" width="796" height="140" /></a></p>
<p><strong>jQuery</strong></p>
<p><a rel="attachment wp-att-1456" href="http://www.formboss.net/blog/2011/10/jquery-vs-prototype-part-1/jquery-js-server-gzip/"><img class="alignnone size-full wp-image-1456" title="jquery-js-server-gzip" src="http://www.formboss.net/blog/wp-content/uploads/2011/10/jquery-js-server-gzip.png" alt="" width="796" height="140" /></a></p>
<p>The minified version of Prototype is made via <a title="JS Minifier" href="http://fmarcia.info/jsmin/test.html" target="_blank">this minifier</a>, and as we can see is essentially the same size as jQuery.</p>
<p>However, note that the non-minified version of Prototype is only ~5KB larger, and just as importantly, only take ~3 ms of extra server processing time (remember that gzipping in Apache is not free!). In other words we&#8217;re about even in that <strong>we do not need to create a minified version of Prototype</strong> and we&#8217;ll still deliver, in terms of processor load and payload size, the same thing.</p>
<h2>In Conclusion</h2>
<p>In this first post we&#8217;ve found that when properly delivered both libraries are essentially the same size. I would actually give Prototype the win however, as its smaller uncompressed size means we can simply plop the uncompressed version in to our delivery or &#8216;live&#8217; section, and then in testing, instead of nonsensical minified error messages get actual line numbers we can refer back to. True this shouldn&#8217;t happen often, (it should be our code with the error, not Prototype or jQuery), but still handy in the larger scheme.</p>
<p>In non-gzipped environments however it&#8217;s clear that jQuery gets the win. This will be important for shared hosting plans of anywhere else we do not have access to server-side gzipping.</p>
<p>It&#8217;s also noteworthy that in order for Prototype to gain some of the more advanced animation framework goodness that (I assume) jQuery already has in the base library, we&#8217;d need to add <a title="script.aculo.us" href="http://script.aculo.us/" target="_blank">Script.aculo.us</a>, which would of course make the total payload larger.</p>
<p>Those considerations aside, what&#8217;s fascinating to me is that the <em>perception </em>of jQuery being &#8220;the&#8221; light-weight library. In the past 3 years I firmly believe this has been the primary driving force behind its mass adoption and popularity. I don&#8217;t know about you but I&#8217;ve been specifically told by bosses to not include Prototype <em>because </em>of its size &#8212; but at the same time given the go-ahead for jQuery. I&#8217;ve also made similar decisions for FormBoss based on the same reasoning (<em>though not to instead use jQuery, just vanilla JavaScript</em>).</p>
<p>Now that this is no longer true for the right environments (and truth be told, this has always been the case in the right environments), I think the time&#8217;s right for Prototype to take back some of the users it rightly deserves.</p>
<p>The irony of course is back in 2008 jQuery 1.4.2 <em>was </em>in fact smaller: 3549 lines of code vs. Prototype 1.6.0.1&#8242;s 4321. But success comes with a price, and jQuery&#8217;s potential bloat can only be a good thing for users looking to &#8216;trim&#8217;. How wonderful : )</p>
<p>Please understand though: I have nothing against jQuery, I simply feel that Prototype deserves more recognition and is in many ways the superior library for some specific types of work.</p>
<p>This will only happen though, and I cannot be more serious, if the Prototype folks get off their collective butts and do the same thing as jQuery &#8211;  advertise, as prominently as you can, the fact that when minified <em>and </em>gzipped your library <strong>is the same size</strong>.</p>
<h2>Links</h2>
<p><a title="Prototype and jQuery" href="http://thinkrelevance.com/blog/2009/01/12/why-i-still-prefer-prototype-to-jquery.html">http://thinkrelevance.com/blog/2009/01/12/why-i-still-prefer-prototype-to-jquery.html</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.formboss.net/blog/2011/10/jquery-vs-prototype-part-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Benchmarks: JavaScript vs. PHP vs. HPHP vs C++</title>
		<link>http://www.formboss.net/blog/2011/07/benchmarks-javascript-vs-php-vs-hphp-vs-c/</link>
		<comments>http://www.formboss.net/blog/2011/07/benchmarks-javascript-vs-php-vs-hphp-vs-c/#comments</comments>
		<pubDate>Wed, 06 Jul 2011 20:04:01 +0000</pubDate>
		<dc:creator>grdinic</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Linux/Web Servers]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://www.formboss.net/blog/?p=1228</guid>
		<description><![CDATA[Just a quick spattering of some benchmarks I ran while testing a program I&#8217;m developing internally. The first three are of the fannkuch benchmark found on the sunspider test site, only ported over to C++ and PHP in addition to the JS version. The browser used for all tests was Firefox 5. The HPHP listing [...]]]></description>
			<content:encoded><![CDATA[<p>Just a quick spattering of some benchmarks I ran while testing a program I&#8217;m developing internally.</p>
<p>The first three are of the <a title="Sunspider Benchmark" href="http://www.webkit.org/perf/sunspider-0.9/access-fannkuch.html" target="_blank">fannkuch benchmark found on the sunspider test site</a>, only ported over to C++ and PHP in addition to the JS version. The browser used for all tests was Firefox 5.</p>
<p>The HPHP listing is a compiled <a title="Hip Hop PHP" href="https://github.com/facebook/hiphop-php/wiki/" target="_blank">Hip Hop PHP</a> version, which is interesting as it shows the relative difference between it and vanilla PHP.</p>
<p>The last item, Benchmark.php, is the same benchmark file you&#8217;ll find in a <a title="PHP Source" href="http://www.php.net/downloads.php" target="_blank">PHP source download</a>.</p>
<p>See the full benchmarks after the jump!</p>
<p><span id="more-1228"></span></p>
<p><strong>access-fannkuch &#8211; n=9</strong></p>
<p>JavaScript: 0.204</p>
<p>PHP: 1.624</p>
<p>HPHP: 0.538</p>
<p>C++ .20</p>
<p><strong>access-fannkuch &#8211; n=10</strong></p>
<p>JavaScript: 3.062</p>
<p>PHP: 19.058</p>
<p>HPHP: 6.395</p>
<p>C++ .189</p>
<p><strong>access-fannkuch &#8211; n=11</strong></p>
<p>JavaScript: 40.297</p>
<p>PHP: ~4 minutes</p>
<p>HPHP: 23.713</p>
<p>C++ 2.265</p>
<p><strong>Benchmark.php</strong></p>
<p>PHP: 2.542</p>
<p>HPHP: 0.547</p>
]]></content:encoded>
			<wfw:commentRss>http://www.formboss.net/blog/2011/07/benchmarks-javascript-vs-php-vs-hphp-vs-c/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Testing JavaScript In Modern Browsers</title>
		<link>http://www.formboss.net/blog/2011/06/testing-javascript-in-modern-browsers/</link>
		<comments>http://www.formboss.net/blog/2011/06/testing-javascript-in-modern-browsers/#comments</comments>
		<pubDate>Sat, 04 Jun 2011 17:33:00 +0000</pubDate>
		<dc:creator>grdinic</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://www.formboss.net/blog/?p=1222</guid>
		<description><![CDATA[I recently installed Internet Explorer 9, and while the browsers interface seems nice, the JavaScript performance in terms of running FormBoss leaves something to be desired: In short, it&#8217;s completely unusable. This was not at all the case in IE 8, and when you consider IE 9 was supposed to be the release that finally [...]]]></description>
			<content:encoded><![CDATA[<p>I recently installed Internet Explorer 9, and while the browsers interface seems nice, the JavaScript performance in terms of running FormBoss leaves something to be desired: In short, it&#8217;s completely unusable.</p>
<p>This was not at all the case in IE 8, and when you consider IE 9 was supposed to be the release that finally fixed JavaScript this is quite disheartening.</p>
<p>As any serious JavaScript programmer can attest to, the irony of IE has always been that in many ways its been more &#8216;correct&#8217; in terms of standards than the other browsers. That is, what passes in Firefox in terms of JavaScript code fails in IE not because IE is wrong, but because Firefox is so forgiving (and by extension, wrong). This is doubly true when we add a JavaScript library like <a href="http://www.prototypejs.org/">Prototype JS</a> into the mix, in that the libraries attempts to smooth over browser differences may expose us to subtitle differences in core JavaScript behavior.</p>
<p>On that springs to mind is how some Prototype JS objects property counts are handled. In Firefox an object may be shown to have a length of 1, but in IE that same object had a length of 2. Another example, if memory serves, had to do with valid names of objects. IE has always been more strict in terms of using names that start with numbers, and so on.</p>
<p>Such differences can be hard to spot in production code, and almost always leads to hours of careful testing and debugging.</p>
<p>Thus, as part of my own production process I&#8217;d like to share two links that may help you determine if such issues reside in your code or the browser/library begin used.</p>
<h4>Google Labs Sputnik JavaScript Test</h4>
<p><a title="Sputnik Test" href="http://sputnik.googlelabs.com/">http://sputnik.googlelabs.com/</a></p>
<p>This test is very interesting to me as it confirms, among other things, that IE 9&#8242;s JavaScript engine is generally more &#8216;correct&#8217; in terms of standards that the competition. For example, when run in IE 9 I get 71 failed tests, whereas <a title="Chrome Canari" href="http://tools.google.com/dlpage/chromesxs">Chrome Canari</a> generates 136 and Firefox 4 181.</p>
<p>In almost all of the cases that &#8216;fail&#8217; we see the failed test is something the casual JavaScript author may easily do.</p>
<p>For example, in test s12.5_A9_T1 we check for a function declaration within an &#8216;if&#8217; statement:</p>
<pre>// Copyright 2009 the Sputnik authors.  All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/**
* @name: S12.5_A9_T1;
* @section: 12.5;
* @assertion: Function declaration within an "if" statement is not allowed;
* @description: Declaring function within an "if" statement;
* @negative;
*/

if (true) {
    function __func(){};
} else {
    function __func(){};
}

testCompleted();</pre>
<p>Have I ever done this? No. Could I see others or even me late at night? Sure. The point being that as you peruse some of the test that say, Firefox 4 fails, it becomes obvious that many of the failures stem from Firefox being &#8216;fast and easy&#8217; with some of the rules, which ironically, can make creating JavaScript code easier.</p>
<h4>Framework Library Test</h4>
<p><a title="Framework Test" href="http://dante.dojotoolkit.org/taskspeed/">http://dante.dojotoolkit.org/taskspeed/</a></p>
<p>This test highlights the differences in the major JavaScript libraries. Of core importance to me are the functions that manipulate the DOM, such as <em>append</em>, <em>insertbefore</em>, <em>insertafter</em>, and so on.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.formboss.net/blog/2011/06/testing-javascript-in-modern-browsers/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Sunspider Benchmark in C++</title>
		<link>http://www.formboss.net/blog/2011/04/sunspider-benchmark-in-c/</link>
		<comments>http://www.formboss.net/blog/2011/04/sunspider-benchmark-in-c/#comments</comments>
		<pubDate>Sat, 23 Apr 2011 20:27:54 +0000</pubDate>
		<dc:creator>grdinic</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[benchmark]]></category>
		<category><![CDATA[fannkuch]]></category>
		<category><![CDATA[sunspider]]></category>

		<guid isPermaLink="false">http://www.formboss.net/blog/?p=1168</guid>
		<description><![CDATA[The Sunspider JavaScript Benchmark is a popular test of Web Browser performance. As great as the newest browsers are I though it would be interesting to take a random test and port it to C++ for the sake of comparison. I decided the rather short fannkuch test was a good candidate. The results: Not surprisingly [...]]]></description>
			<content:encoded><![CDATA[<p>The <a href="http://www.webkit.org/perf/sunspider-0.9.1/sunspider-0.9.1/driver.html">Sunspider JavaScript Benchmark</a> is a <a href="http://ie.microsoft.com/testdrive/benchmarks/sunspider/default.html">popular test</a> of Web Browser performance.</p>
<p>As great as the newest browsers are I though it would be interesting to take a random test and port it to C++ for the sake of comparison.</p>
<p>I decided the rather short <a href="http://www.webkit.org/perf/sunspider-0.9/access-fannkuch.html">fannkuch </a>test was a good candidate. The results:</p>
<p><a rel="attachment wp-att-1169" href="http://www.formboss.net/blog/2011/04/sunspider-benchmark-in-c/fannkuch-benchmark/"><img class="alignnone size-full wp-image-1169" title="fannkuch-benchmark" src="http://www.formboss.net/blog/wp-content/uploads/2011/04/fannkuch-benchmark.png" alt="" width="680" height="422" /></a></p>
<p>Not surprisingly the C++ version is 18x faster than Firefox and 8x faster than Chrome. For the curious, the ported C++ code is after the jump.</p>
<p>I should mention one thing changed from the stock Sunspider site (e.g., the link above), is the number of iterations was upped from 8 to 10. At 8 iterations the C++ version was sub-millisecond, meaning I&#8217;d have had to roll a custom assembly timer to get a benchmark value. That said, when we lower the iterations down to 9, the stack heavy algorithm starts to benefit the browsers more, with Chrome coming in only 3 times slower and Firefox 11. </p>
<p>Lower the iteration count to the &#8220;stock&#8221; 8 and Firefox actually catches up to Chrome, with both browsers reporting ~21ms. Interesting. </p>
<p><span id="more-1168"></span></p>
<p>The C++ Code</p>
<pre class="brush: cpp; title: ; notranslate">
int MainWindow::Fannkuch(int n)
{

    int check = 0;
    int perm[n];
    int perm1[n];
    int count[n];
    int maxPerm[n];
    int maxFlipsCount = 0;
    int m = n - 1;

    for (int i = 0; i &lt; n; i++){
        perm1[i] = i;
    }

    int r = n;

    while (true) {

        // write-out the first 30 permutations
        if (check &lt; 30){
            int s = 0;
            for(int i=0; i&lt;n; i++) s += (perm1[i]+1);
            check++;
        }

        while (r != 1) { count[r - 1] = r; r--; }

        if (!(perm1[0] == 0 || perm1[m] == m)) {
            for (int i = 0; i &lt; n; i++) perm[i] = perm1[i];
            int flipsCount = 0;
            int k;

            while (!((k = perm[0]) == 0)) {
                int k2 = (k + 1) &gt;&gt; 1;
                for (int i = 0; i &lt; k2; i++) {
                    int temp = perm[i]; perm[i] = perm[k - i]; perm[k - i] = temp;
                }
                flipsCount++;
            }

            if (flipsCount &gt; maxFlipsCount) {
                maxFlipsCount = flipsCount;
                for (int i = 0; i &lt; n; i++) maxPerm[i] = perm1[i];
            }
        }

        while (true) {
            if (r == n) return maxFlipsCount;

            int perm0 = perm1[0];
            int i = 0;

            while (i &lt; r) {
                int j = i + 1;
                perm1[i] = perm1[j];
                i = j;
            }

            perm1[r] = perm0;
            count[r] = count[r] - 1;

            if (count[r] &gt; 0) break;
            r++;
        }
    }

}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.formboss.net/blog/2011/04/sunspider-benchmark-in-c/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Five Times 2 &#8211; HTML 5 For Safari 5</title>
		<link>http://www.formboss.net/blog/2010/06/five-times-2-html-5-for-safari-5/</link>
		<comments>http://www.formboss.net/blog/2010/06/five-times-2-html-5-for-safari-5/#comments</comments>
		<pubDate>Fri, 11 Jun 2010 02:21:20 +0000</pubDate>
		<dc:creator>grdinic</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[HTML 5]]></category>

		<guid isPermaLink="false">http://www.formboss.net/blog/?p=458</guid>
		<description><![CDATA[Apple released Safari 5 on June 9th, the fastest and most advanced browser from Apple yet. It&#8217;s loaded with new features and enhancements, and from a cursory look, this is an intriguing release indeed. Thing is though, if your a non-techie all this talk of HTML 5 probably makes you say &#8220;Wah?&#8221; &#8212; While  those [...]]]></description>
			<content:encoded><![CDATA[<p>Apple released Safari 5 on June 9th, the fastest and most advanced browser from Apple yet. It&#8217;s loaded with new features and enhancements, and from a <a title="Safari 5 Features" href="http://www.apple.com/safari/whats-new.html" target="_blank">cursory look</a>, this is an intriguing release indeed.</p>
<p>Thing is though, if your a non-techie all this talk of HTML 5 probably makes you say &#8220;Wah?&#8221; &#8212; While  those of us in the development community are left wondering when we&#8217;ll get to implement this cool stuff as the giant elephant in the room <a title="IE" href="http://www.microsoft.com/windows/internet-explorer/default.aspx" target="_blank">sits docilely in the corner</a>.</p>
<p>It&#8217;s a confusing release really, filled with more promise and hope than tangible benefit&#8211;or is it?</p>
<p><span id="more-458"></span></p>
<p>As a guy who runs a web software company I thought I&#8217;d share my quick thoughts on Safari 5 and provide some links to learn more.</p>
<h2>HTML 5</h2>
<p><strong>HTML5 AJAX History</strong></p>
<p>This is an interesting one in that it&#8217;s a feature in need of a web infrastructure to support it&#8211;or at least if I understand the feature correctly. I assume this is a system for storing application state, but I haven&#8217;t had much luck finding out for sure. Regardless, it&#8217;s interesting to me as someone who wrote a <a title="Mariner" href="http://www.floridamariner.com" target="_blank">full AJAX based web site</a> that utilizes AJAX history state saving. It was done using a script called <a title="Real Simple History" href="http://code.google.com/p/reallysimplehistory/" target="_blank">Real Simple History</a>, and was as you would expect, a direct answer to the annoyances of losing your save state if the user hit the back, reload, or forward button. It works well enough, but just as with HTML Draggables, would be nice to have built in.</p>
<p><strong>HTML5 forms validation</strong></p>
<p>Sorry, not too informative, but I did find <a title="HTML 5 Form Validation" href="http://stackoverflow.com/questions/432933/will-html-5-validation-be-worth-the-candle" target="_blank">this link</a> which describes more on this topic.</p>
<p><strong>WebSocket</strong></p>
<p>I like to think of this as a extension of the HTTP Request object introduced in IE 5 way back in &#8217;99. The basic idea is that we can open a direct link to a server on what&#8217;s called a Full Duplex channel (e.g. your telephone), which allows simultaneous two-way communication.</p>
<p><a title="PHP Web Socket" href="http://code.google.com/p/phpwebsocket/" target="_blank">http://code.google.com/p/phpwebsocket/</a></p>
<p>What is this good for? Chat logs I suppose, but it may lead to more advanced types of form validation&#8230;</p>
<p><strong>Web workers</strong></p>
<p>I&#8217;ve actually covered these guys in <a title="Web Workers" href="../2010/05/multi-threaded-javascript-a-quick-look/" target="_blank">another post</a> on this blog, but the basic idea is  that web can run concurrent JavaScript code to speed up execution. Now  Safari 4 already supported Web Workers, though with a reduced  feature-set as compared to FireFox. So the real question is, have they  been enhanced in any appreciable way? I&#8217;ll have to test the feature set in a future post, but for now, here&#8217;s a quick look at performance between FireFox 3.6.3 and Safari 5:</p>
<p><em>Firefox 3.6.3:</em></p>
<p><span style="color: #808000;">Fibonacci Set 1 Time Taken: 1.16</span></p>
<p><em>Safari 5 (initial release)</em></p>
<p><span style="color: #808000;">Fibonacci Set 1 Time Taken: 0.2</span></p>
<p>Of course this is the horrible inefficient stack smashing way, the optimised iterative version favors FireFox slightly:</p>
<p><em>Firefox 3.6.3:</em></p>
<p><span style="color: #808000;">Fibonacci Set 1 Time Taken: 1.08</span></p>
<p><em>Safari 5:</em></p>
<p><span style="color: #808000;">Fibonacci Set 1 Time Taken: 1.52</span></p>
<p><strong>HTML5 draggable attribute</strong></p>
<p>This is an interesting one, if for no other reason than here we have another Microsoft originated API from IE 5!</p>
<p>http://html5doctor.com/native-drag-and-drop/</p>
<p>As far as it&#8217;s integration into web applications&#8211;I think the greatest benefit of a native API to handle drag and drop will be from a performance perspective. Right now in FormBoss, for example, dragging multiple items isn&#8217;t as precise as I would like it to be. This is not necessarily a performance problem, but a native method should mean we can sample more efficiently during the drag operation, which should help smooth things out and improve precision.</p>
<p>Their is more to it of course, to which I simply defer to: <a title="HTML 5 Doctor" href="http://html5doctor.com/" target="_blank">http://html5doctor.com</a></p>
<h2>Developer Tools and Closing Comments</h2>
<p>The last thing I want to look at is the all-important subject of Safari 5 as a developer friendly release.</p>
<p>FireBug simply rules them all&#8211;this has been, and most likely will continue to be, the clarion call for all serious web developers. Yet in the recent years it seems as if inline JavaScript debugging is becoming the norm, not the exception. IE8 has a debugger, Chrome, and of course Safari.</p>
<p>Problem is, they&#8217;ve always fallen <em>well </em>short of Firebug for one simple reason: FireBug is about more than just debugging, it&#8217;s about the DOM too. Without a good way of viewing the DOM a debugger is nearly useless for complex work. To be clear, by DOM I mean the <em>entire DOM</em><em> starting from the window </em>element, not just the visible page bits from the <em>HTML </em>element on down. FormBoss, like most web applications, makes extensive use of the root DOM object to store objects and arrays.</p>
<p>The strange thing is Safari will gladly show you the <em>window </em>element if you open the Console and type:</p>
<div class="geshi no javascript">
<ol>
<li class="li1">
<div class="de1"><span class="kw1">eval</span> <span class="br0">&#40;</span>window<span class="br0">&#41;</span></div>
</li>
</ol>
</div>
<p>&#8230;but not from the comfort of the main debugger, or even from a separate DOM tab.</p>
<p>Unfortunately, while the developer tools in Safari 5 seem very slick, they do not address the DOM viewing issue, and they also seem to be a touch unstable. While viewing the property of a paused debugging session the entire browser crashed. I&#8217;ve had FireFox get twitchy, but not outright crash.</p>
<p>That said, the tools are slick, as I said. Syntax coloring is very nice to see, as is the clean and intuitive user interface. Now if they could only add a <em>proper </em>DOM inspector!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.formboss.net/blog/2010/06/five-times-2-html-5-for-safari-5/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Multi-Threaded JavaScript &#8212; A Quick Look.</title>
		<link>http://www.formboss.net/blog/2010/05/multi-threaded-javascript-a-quick-look/</link>
		<comments>http://www.formboss.net/blog/2010/05/multi-threaded-javascript-a-quick-look/#comments</comments>
		<pubDate>Thu, 20 May 2010 00:31:18 +0000</pubDate>
		<dc:creator>grdinic</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Multi Threaded]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://www.formboss.net/blog/?p=212</guid>
		<description><![CDATA[The strange thing about this post is that this isn&#8217;t exactly news&#8211;ever since FireFox 3.5 came out in June of &#8217;09, and along with Safari 4 and Google Chrome using a slightly different mechanism, these browsers all support OS Level multi-threading. The question is, should you care? The short answer for right now is absolutely, [...]]]></description>
			<content:encoded><![CDATA[<p>The strange thing about this post is that this isn&#8217;t exactly news&#8211;ever since FireFox 3.5 came out in June of &#8217;09, and along with Safari 4 and Google Chrome using a <a title="Google Gears Threading API" href="http://code.google.com/apis/gears/api_workerpool.html" target="_blank">slightly different mechanism</a>, these browsers all support OS Level multi-threading.</p>
<p>The question is, should you care?</p>
<p><span id="more-212"></span></p>
<p>The short answer for right now is absolutely, just don&#8217;t expect to place any of your multi-threaded code into a live environment any time soon. Until Internet Explorer decides to implement this API we&#8217;re left with a world where more than half your users won&#8217;t see your threaded code anyway.</p>
<p>Of course this is a pity, as it&#8217;s not hard to imagine the many uses spawning worker threads would have. As I type this I&#8217;m looking at one right now&#8230;the TinyMCE text editor. Sure it&#8217;s fine for most web editing tasks, but in FormBoss there are several instances of hooks I need to write into the processing engine to update various data structures, and sometimes these really take a hit with larger data sets. Of course loading times are also quite slow, even on relatively fast machines like I&#8217;m using now.</p>
<p>Opining aside, the purpose of this post is to learn a bit more about these guys, how they are used, and what type of performance boost you can expect.</p>
<h2>General use</h2>
<p>I&#8217;m going to stick with the kind of threads that FireFox and Safari use.</p>
<p>The basic work flow is you write a calling script like this (<em>index.html</em>):</p>
<div class="geshi no javascript">
<ol>
<li class="li1">
<div class="de1"><span class="kw2">var</span> iteration = <span class="nu0">30</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw2">var</span> worker1 = <span class="kw2">new</span> Worker<span class="br0">&#40;</span><span class="st0">&#39;fibonacci.js&#39;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">worker1.<span class="me1">onmessage</span> = <span class="kw2">function</span><span class="br0">&#40;</span>event<span class="br0">&#41;</span><span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;<span class="kw1">if</span><span class="br0">&#40;</span>event.<span class="me1">data</span> == <span class="st0">&#39;Done!&#39;</span><span class="br0">&#41;</span><span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;StopTimer<span class="br0">&#40;</span><span class="st0">&#39;fib1timer&#39;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;<span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;document.<span class="me1">getElementById</span><span class="br0">&#40;</span><span class="st0">&#39;fib1&#39;</span><span class="br0">&#41;</span>.<span class="me1">innerHTML</span> += event.<span class="me1">data</span> + <span class="st0">&#39;&lt;br<span class="es0">\></span>&#39;</span>;</div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span>;</div>
</li>
<li class="li1">
<div class="de1">worker1.<span class="kw3">onerror</span> &#8211; <span class="kw2">function</span><span class="br0">&#40;</span>error<span class="br0">&#41;</span><span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;dump<span class="br0">&#40;</span><span class="st0">&quot;Erorr with thread:&quot;</span> + error.<span class="me1">message</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;<span class="kw1">throw</span> error;</div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span>;</div>
</li>
<li class="li1">
<div class="de1"><span class="co1">// call worker 1</span></div>
</li>
<li class="li1">
<div class="de1">worker1.<span class="me1">postMessage</span><span class="br0">&#40;</span>iteration<span class="br0">&#41;</span>;</div>
</li>
</ol>
</div>
<p>&#8230;whose job it is to create a worker (the second line), listen for messages from the worker, listen for errors from the worker, and finally, start the worker with some task (the last line).</p>
<p>The interesting thing to me about this code is how in the first line we initialize a Worker by passing in an argument of a JavaScript file. This is not a mistake, it&#8217;s how these guys are created. We do not pass functions, we pass files. I&#8217;ve heard grumbling about this, but I personally think it&#8217;s rather appropriate, at least for now.</p>
<p>Before we take a look at that file argument code though, note the event handlers (onmessage, onerror). These are required, and the names cannot be changed as they are built in functions that need an implementation from your application.</p>
<p>Right, on to the <em>fibonacci.js</em> fie:</p>
<div class="geshi no javascript">
<ol>
<li class="li1">
<div class="de1"><span class="co1">// main fibonaccci cycle &#8212; careful with anything over 30!</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw2">function</span> fib<span class="br0">&#40;</span>n<span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;<span class="kw2">var</span> s = <span class="nu0">0</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;<span class="kw1">if</span><span class="br0">&#40;</span>n == <span class="nu0">0</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;<span class="kw1">return</span><span class="br0">&#40;</span>s<span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;<span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;<span class="kw1">if</span><span class="br0">&#40;</span>n == <span class="nu0">1</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;s += <span class="nu0">1</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;<span class="kw1">return</span><span class="br0">&#40;</span>s<span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;<span class="br0">&#125;</span> <span class="kw1">else</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;<span class="kw1">return</span><span class="br0">&#40;</span>fib<span class="br0">&#40;</span>n &#8211; <span class="nu0">1</span><span class="br0">&#41;</span> + fib<span class="br0">&#40;</span>n &#8211; <span class="nu0">2</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;<span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="co1">// worker thread &#39;gateway&#39; function.</span></div>
</li>
<li class="li1">
<div class="de1">onmessage = <span class="kw2">function</span><span class="br0">&#40;</span>event<span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;<span class="kw2">var</span> n = parseInt<span class="br0">&#40;</span>event.<span class="me1">data</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;<span class="kw2">var</span> i;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;<span class="kw1">for</span><span class="br0">&#40;</span>i = <span class="nu0">0</span>; i <span class="sy0">&lt;</span>= n; i++<span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;postMessage<span class="br0">&#40;</span>fib<span class="br0">&#40;</span>i<span class="br0">&#41;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;<span class="co1">// wasteful, but shows how the messaging system can be called</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;<span class="kw1">if</span><span class="br0">&#40;</span>i == n<span class="br0">&#41;</span><span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;postMessage<span class="br0">&#40;</span><span class="st0">&#39;Done!&#39;</span><span class="br0">&#41;</span>;    </div>
</li>
<li class="li1">
<div class="de1">&nbsp;<span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;<span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span></div>
</li>
</ol>
</div>
<p>So the basic idea is we define an onmessage event listener to wait for our initial call. Think of this as the &#8216;gateway&#8217; into the threaded function. Once this message is received by <em>fibonacci.js</em>, we grab parameters from the event.data argument and kick off our first iteration of the fibo cycle by issuing a call to postMessage(fib(i)).</p>
<p>As we are <em>passing a function as an argument</em>, and because that<em> function returns a value</em>, the postMessage(fib(i)) call will receive a Fibonacci value back. If we look at the first code block again (<em>index.html)</em>, you&#8217;ll notice we defined a event handler for these postMessage() events, the function onmessage().</p>
<p>So just to be clear: in<em> index.html</em> we start our thread by calling:</p>
<pre>worker1.postMessage(iteration);</pre>
<p>This call is received by the event handler in <em>fibonacci.js</em> via onmessage(). Then, when we want to talk back to <em>index.html</em> from <em>fibonacci.js</em>, we do so once again via postMessage(). This call is then also handled by an event handler called onmessage().</p>
<p>In other words, both scripts have a postMessage() call, and both have event handlers for this call, onmessage().</p>
<p>This is super important to understanding how Web Workers function with respect to their inherit limitations&#8211;the long and short of it is when we spin off one of these threads the code in the external .js file is for all intents and purposes disconnected from your main script. The code in the web worker cannot change the DOM, and can only pass values back to your main script via postMessage().</p>
<p>Thus, in the code above when the fib() function returns a value it does so as an argument to the postMessage() function call, this value is then received by the &#8220;main&#8221; script (the top one, <em>index.html</em>), which updates the DOM via:</p>
<pre>document.getElementById('fib1').innerHTML += event.data + '&lt;br\&gt;';</pre>
<p>So yes we can update the DOM with results and data from our threaded functions, but not from within the Web Worker, only from the messages we send back to the calling script.</p>
<p>This actually brings up two important points:</p>
<ol>
<li>Safari only supports a simplified version of the messaging system. Whereas FireFox supports full on JSON, Safari only support simple values.</li>
<li>Communication has a cost&#8230;</li>
</ol>
<h2>Communication has a cost</h2>
<p>Yes it does. One of the main hassles of threaded programming is dealing with the headaches of race conditions, deadlocks, and other data dependencies. Web Workers hide much of this from us, making it quite hard to create such problems at the cost of some flexibility.</p>
<p>That said, to help illustrate how web workers can be used, I&#8217;ll created three different test cases (<em> **see download link below</em>).</p>
<p><em>single-thread</em></p>
<p><em>worker-threads</em></p>
<p><em>worker-threads-optimized</em></p>
<p><em>single-thread</em> , as the name suggests, simply takes our fib() function and calls it twice on page load, both with 30 iterations. Some defining characteristics of this approach is we loop around 14,098,246 times, and our web page is effectively &#8216;blocked&#8217; during this time, causing the DOM to freeze until the operation finishes.</p>
<p><em>worker-threads</em> is basically the same code as above, but now we define two Web Workers, both of which call the same <em>fibonacci.js</em> file. We then loop through the same code as we do in <em>single-thread</em>, but because each call is using its own thread, the operation finishes roughly twice as fast (provided you have a two-core machine!).</p>
<p>Some characteristics of this approach are quite pleasing indeed. Yes the operation finished twice as fast, but this is kind of a generic case anyway. For me, the real benefit is a) our timer call actually runs independently of the main operation and provides an accurate result. b) the DOM is no longer blocked, in fact it&#8217;s updated dynamically, which is a pretty neat effect.</p>
<p>Finally, we have <em>worker-threads-optimized</em>. In this case we give up the embarrassingly inefficient recursion-from-hell fib() function and use a far more efficient iterative version:</p>
<div class="geshi no javascript">
<ol>
<li class="li1">
<div class="de1"><span class="kw2">function</span> fib<span class="br0">&#40;</span>length<span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;<span class="kw1">for</span><span class="br0">&#40;</span> l = <span class="br0">&#91;</span><span class="nu0">0</span>,<span class="nu0">1</span><span class="br0">&#93;</span>, i = <span class="nu0">2</span>, x = <span class="nu0">0</span>; i <span class="sy0">&lt;</span> length; i++ <span class="br0">&#41;</span><span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;l.<span class="me1">push</span><span class="br0">&#40;</span>l<span class="br0">&#91;</span>x++<span class="br0">&#93;</span> + l<span class="br0">&#91;</span>x<span class="br0">&#93;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="co1">//postMessage(l[x]);</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;<span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;<span class="kw1">return</span> l;</div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span></div>
</li>
</ol>
</div>
<p>When I first ran this code I was surprised to see just how much faster it was. With the old function anything over 35 was trouble. With this version we can easily pass 10,000,000.</p>
<p>But there in was a problem: During testing I would set the sequence number to around 300,000 for each of my two threads and wait as I monitored CPU load. Problem was, my CPU load never went over 25% on a four-core machine&#8211;I was running single threaded again. But how? Did I run into some limitation of what files could be run, what variables could be used, or what functions called?</p>
<p>I won&#8217;t lie: I pondered over for quite a while before it finally dawned on me: the <em>worker-threads</em> version, while computationally expensive, was doing almost nothing to tax the DOM. At 30 iterations each the DOM would receive a request to update every 150 milliseconds or so, leaving plenty of time for the Web Workers and browser to grind away. In other words, we could run at the full potential of the threaded code because the DOM update calls we infrequent enough to not matter.</p>
<p>But not so with the new version. The new version was <em>absolutely pounding</em> the DOM with hundreds of thousands of requests every second. Their was no way it was going to keep up, and so in the end the browser itself started blocking the postMessage() function calls.</p>
<p>That&#8217;s why that postMessage() call above is commented out. So long as we&#8217;re not trying to call that we use both cores as expected. Lesson learned: If you truly want parallelism you&#8217;ll need to forgo DOM communication if the number of calls becomes too great relative to the time between each each DOM update. </p>
<p>In the end, the gateway function ended up being:</p>
<div class="geshi no javascript">
<ol>
<li class="li1">
<div class="de1"><span class="co1">// worker thread &#39;gateway&#39; function.</span></div>
</li>
<li class="li1">
<div class="de1">onmessage = <span class="kw2">function</span><span class="br0">&#40;</span>event<span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;postMessage<span class="br0">&#40;</span><span class="st0">&#39;start!&#39;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;fib<span class="br0">&#40;</span>parseInt<span class="br0">&#40;</span>event.<span class="me1">data</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;postMessage<span class="br0">&#40;</span><span class="st0">&#39;Done!&#39;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span>;</div>
</li>
</ol>
</div>
<p>When we first enter the function we pass a simple start message, and when done, pass a message that we&#8217;re done.</p>
<h2>In Conclusion</h2>
<p>What a wonderful world it could be if we had better standards in the world of web browsers. Alas, for the foreseeable future Web Workers shall remain an enigma to most, which is a shame. Used right they can provide a significantly improved user experience, as well as open the doors to a more dynamic and interesting web. Let the wait begin!</p>
<h2>Download the scripts discussed in this post!</h2>
<p><a href="http://www.formboss.net/blog/wp-content/uploads/2010/05/worker-thread-benchmarks.zip">worker-thread-benchmarks</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.formboss.net/blog/2010/05/multi-threaded-javascript-a-quick-look/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

