<?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>unscriptable.com &#187; dojo</title>
	<atom:link href="http://unscriptable.com/category/javascript/dojo/feed/" rel="self" type="application/rss+xml" />
	<link>http://unscriptable.com</link>
	<description>Just another WordPress site</description>
	<lastBuildDate>Mon, 26 Mar 2012 01:47:11 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>The first annual dojoconf!</title>
		<link>http://unscriptable.com/2011/09/22/the-first-annual-dojoconf/</link>
		<comments>http://unscriptable.com/2011/09/22/the-first-annual-dojoconf/#comments</comments>
		<pubDate>Thu, 22 Sep 2011 11:46:06 +0000</pubDate>
		<dc:creator>John Hann</dc:creator>
				<category><![CDATA[AMD]]></category>
		<category><![CDATA[dojo]]></category>
		<category><![CDATA[Javascript]]></category>

		<guid isPermaLink="false">http://unscriptable.com/?p=751</guid>
		<description><![CDATA[I just got back from the first ever dojoconf in Washington DC. I asked Dylan and Chris if they were planning to do it annually and I got something equivalent to &#8220;F**K YEAH!&#8221; Good. cuz it was awesome. I was honored to present about AMD Module Patterns at dojoconf. My slides are here. A half [...]]]></description>
			<content:encoded><![CDATA[<p>I just got back from the first ever <a href="http://dojoconf.com/">dojoconf</a> in Washington DC.  I asked <a href="http://twitter.com/dylans">Dylan</a> and <a href="http://twitter.com/voodootikigod">Chris</a> if they were planning to do it annually and I got something equivalent to &#8220;F**K YEAH!&#8221;</p>
<p>Good. cuz it was awesome.  <img src='http://unscriptable.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>I was honored to present about <a href="http://unscriptable.com/code/AMD-module-patterns/">AMD Module Patterns</a> at dojoconf.  My slides are <a href="http://unscriptable.com/code/AMD-module-patterns/">here</a>.  A half hour is not nearly enough time to present on even a couple of patterns.  It didn&#8217;t help that I was high on cold medication, so I think I missed half of the points I wanted to make and missed half my slides at the same time.  <img src='http://unscriptable.com/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley' /> </p>
<p>To rectify the situation, I will write a blog post on each pattern.  My goal is to write about one pattern a day until they&#8217;re all done.  Wish me luck. <img src='http://unscriptable.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>&#8211; John</p>
<p>P.S. This was my first time representing a corporation at a conference.  I have been a full-time employee at <a href="http://lifeimage.com/">lifeIMAGE</a> in Newton, MA since August 2010.  lifeIMAGE sponsored the Hacker Lounge at dojoconf and paid for the awesome <a href="http://unscriptable.com/code/AMD%2Dmodule%2Dpatterns/images/IMG_6958.JPG">dojo minis</a>!  (Btw, we&#8217;re always hiring javascript engineers!)</p>
]]></content:encoded>
			<wfw:commentRss>http://unscriptable.com/2011/09/22/the-first-annual-dojoconf/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Bizarro dojo with a slice of cujo.js [updated]</title>
		<link>http://unscriptable.com/2010/08/19/bizarro-dojo-with-a-slice-of-cujo-js/</link>
		<comments>http://unscriptable.com/2010/08/19/bizarro-dojo-with-a-slice-of-cujo-js/#comments</comments>
		<pubDate>Thu, 19 Aug 2010 13:25:17 +0000</pubDate>
		<dc:creator>John Hann</dc:creator>
				<category><![CDATA[cujo.js]]></category>
		<category><![CDATA[dijit]]></category>
		<category><![CDATA[dojo]]></category>
		<category><![CDATA[Javascript]]></category>

		<guid isPermaLink="false">http://unscriptable.com/?p=649</guid>
		<description><![CDATA[Here is the slideshow from my presentation at the Bocoup Loft on August 15th. For some reason, slideshare barfed on it even after I removed all of the video and audio. Srsly, I tried five different variations. dojo is bizarro jQuery (bocoup) This presentation is in the QuickTime Presentation format. You must use the space [...]]]></description>
			<content:encoded><![CDATA[<p>Here is the slideshow from my presentation at the <a href="http://loft.bocoup.com/">Bocoup Loft</a> on August 15th.  For some reason, slideshare barfed on it even after I removed all of the video and audio. Srsly, I tried five different variations.<br />
<a href='http://unscriptable.com/wp-content/uploads/2010/08/bocoup%20dojo%20is%20bizarro%20jQuery.mov' >dojo is bizarro jQuery (bocoup)</a><br />
This presentation is in the QuickTime Presentation format. You must use the space bar or arrow keys to navigate. (I seem to have to click and hit the arrow keys about a dozen times before the presentation starts.)</p>
<p><strong>[update]</strong><br />
I finally got slideshare to accept the slides!  Here&#8217;s the <a href="http://www.slideshare.net/unscriptable/dojo-is-bizarro-jquery">sideshow</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://unscriptable.com/2010/08/19/bizarro-dojo-with-a-slice-of-cujo-js/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="http://unscriptable.com/wp-content/uploads/2010/08/bocoup%20dojo%20is%20bizarro%20jQuery.mov" length="11532723" type="video/quicktime" />
		</item>
		<item>
		<title>Firefox&#8217;s proposed Resource Packages spec blows!</title>
		<link>http://unscriptable.com/2010/08/03/firefoxs-proposed-resource-packages-spec-sucks/</link>
		<comments>http://unscriptable.com/2010/08/03/firefoxs-proposed-resource-packages-spec-sucks/#comments</comments>
		<pubDate>Wed, 04 Aug 2010 04:47:28 +0000</pubDate>
		<dc:creator>John Hann</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[cujo.js]]></category>
		<category><![CDATA[dojo]]></category>
		<category><![CDATA[HTML / DHTML]]></category>
		<category><![CDATA[In-browser MVC]]></category>

		<guid isPermaLink="false">http://unscriptable.com/?p=634</guid>
		<description><![CDATA[It&#8217;s no secret that one of the keys to a decent user experience is a responsive (fast) user interface. And the most critical component to a fast web app is minimizing the HTTP requests. So it&#8217;s no mystery that people are working on ways to solve this problem. Firefox, of course, is one of the [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s no secret that one of the keys to a decent user experience is a <em>responsive (fast)</em> user interface.  And the most critical component to a fast web app is minimizing the HTTP requests.  So it&#8217;s no mystery that people are working on ways to solve this problem.  </p>
<p>Firefox, of course, is one of the <a href="http://limi.net/articles/resource-packages/">leaders in this area</a>.  Their proposal started out fine.  Here&#8217;s a sample of what it would look like (if you didn&#8217;t read the article):</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">&lt;link rel=&quot;resource-package&quot; 
      type=&quot;application/zip&quot; 
      href=&quot;/static/site-resources.zip&quot;
      content=&quot;javascript/jquery.js;
               css/reset.css;
               css/grid.css;
               css/main.css;
               images/save.png;
               images/info.png&quot; /&gt;</pre></div></div>

<p>You specify that the file, /static/site-resources.zip&#8221;, contains the listed resources.  JavaScript, CSS, and images.  (I imagine SWFs and videos would also be options.)</p>
<p>But for some reason, this concise, <a href="http://limi.net/articles/resource-packages/#inline-html">nearly-valid</a> implementation was trashed in favor of a terse, unfamiliar, and nearly unusable <a href="http://people.mozilla.org/~jlebar/respkg/">alternative</a>.  Here&#8217;s what the spec looks like now:</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">&lt;html packages='[pkg1.zip img1.png script.js styles/style.css]
                [static/pkg2.zip]'&gt;</pre></div></div>

<p>In this bastardization, the packages are specified as an attribute on the document element (<code>&lt;html&gt;</code> tag).  Package definitions in the <code>packages</code> attribute are delimited by square brackets, and the resources within them are delimited by spaces.  </p>
<p>WTF?  Not only is this ugly and non-standard, but it also has some serious drawbacks.  Here&#8217;s why:</p>
<p><span id="more-634"></span></p>
<h3>Reason #1: Any non-trivial web app has hundreds of resources</h3>
<p>The spec says that naming the resources is optional.  However, <em>not</em> naming them causes the browser to block all further downloads until the resource package is downloaded and unzipped.  So to gain optimal performance (not block), we&#8217;ve got to list every single resource?  Not only is that going to be one hell of a large &lt;html&gt; tag, but it also needs to be <em>maintained</em> every time a new resource is added to the app.</p>
<p>The real answer, of course, is to use a dependency-management and packaging solution.  <a href="http://api.dojotoolkit.org/jsdoc/HEAD/dojo.require">dojo.require</a>  and dojo.build do all of the work of resource packaging already.  (<a href="http://requirejs.org/">require.js</a> is a good start at dependency-management for the non-dojo world, but still lacks packaging. Admittedly, dojo only packages javascript and html templates, not css or images.  <a href="http://cujojs.com/">cujo.js</a> will also package css, but still not images.)</p>
<p>With dependency-management, resources are named <em>where they are used</em>, not in some other file.  Having to remember to go back and list every resource in every HTML file is nothing short of a maintenance hassle.</p>
<p>But hmmmm.  Maybe this is a not as big an issue as I originally thought.  If I am using a dependency-management solution, my resource packages would consist of one javascript file, one css file, and a few dozen images.  That&#8217;s still a lot of image files to maintain, but not as bad as maintaining hundreds of javascript and css files.</p>
<p>One of the reasons the browser needs to block is to allow for overrides.  If package, pkg2.zip, has a resource with the same path/name as a resource in a package declared earlier, pkg1.zip, then the resource in pkg2.zip will override (replace) the resource in pkg1.zip.  Therefore, the resources in the packages must be delineated &#8212; either explicitly or by inspecting the package &#8212; before the packages can be used.  </p>
<p>Again, this override functionality is just duplicating dependency-management solutions.  Object-oriented javascript allows us to override methods and properties.  OOCSS allows us to override CSS rules in a different, but equally effective, manner.  (cujo.js also allows for HTML template inheritance / overrides (OOHTML?).)</p>
<p>When done properly (small, concise OOJS, OOHTML, and OOCSS files) and combined with dependency-management, the download size should be exactly the same and amount of extra RAM needed by the browser should be small compared to the resource packaging solution.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">dojo.<span style="color: #660066;">require</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'pkg1'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// base functionality (large)</span>
dojo.<span style="color: #660066;">require</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'pkg2'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// overrides (small)</span></pre></div></div>

<h3>Reason #2: There&#8217;s no way to specify a resource package dynamically</h3>
<p>This is a non-starter for me.  I write client-heavy web apps.  These apps are typically long-running and are served to the browser as a single page.  In other words, the browser doesn&#8217;t load a new page every time the user takes an action.  Google Docs and Google Mail are good examples.  </p>
<p>Using dojo.require and dojo.build, I can package my apps into as many packages as I like.  (They&#8217;re called &#8220;layers&#8221; in dojo.)  This is especially important in a few scenarios:</p>
<ol>
<li>the app will load a package <em>only when needed</em></li>
<li>the user can switch &#8220;theme&#8221; packages dynamically</li>
<li>the user can switch language packages dynamically</li>
</ol>
<p>If Firefox goes forward with the <code>packages</code> attribute on the <code>&lt;html&gt;</code> tag, then I don&#8217;t see how this is possible.  For example:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> html <span style="color: #339933;">=</span> document.<span style="color: #660066;">documentElement</span><span style="color: #339933;">,</span>
    myNewPackage <span style="color: #339933;">=</span> <span style="color: #3366CC;">'pkg3.zip js/myModule.js images/myPng.png'</span><span style="color: #339933;">;</span>
html.<span style="color: #660066;">setAttribute</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'packages'</span><span style="color: #339933;">,</span> html.<span style="color: #660066;">getAttribute</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'packages'</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">' ['</span> <span style="color: #339933;">+</span> myNewPackage <span style="color: #339933;">+</span> <span style="color: #3366CC;">']'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Even if that did work (which I doubt it would), it would undoubtably be unbearably inefficient.  Re-parsing, re-scanning, and re-analyzing every package.</p>
<p>The original proposal did not have this problem.  It&#8217;s a lot simpler to just add a new <code>&lt;link&gt;</code> tag:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> head <span style="color: #339933;">=</span> document.<span style="color: #660066;">documentElement</span>.<span style="color: #660066;">firstChild</span><span style="color: #339933;">,</span> <span style="color: #006600; font-style: italic;">// assumes no comments before head!</span>
    link <span style="color: #339933;">=</span> document.<span style="color: #660066;">createElement</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'link'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
link.<span style="color: #660066;">setAttribute</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'rel'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'resource-package'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
link.<span style="color: #660066;">setAttribute</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'type'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'application/zip'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
link.<span style="color: #660066;">setAttribute</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'href'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'pkg3.zip'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
link.<span style="color: #660066;">setAttribute</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'contents'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'js/myModule.js; images/myPng.png'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
head.<span style="color: #660066;">appendChild</span><span style="color: #009900;">&#40;</span>link<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// in dojo:</span>
<span style="color: #003366; font-weight: bold;">var</span> head <span style="color: #339933;">=</span> dojo.<span style="color: #660066;">query</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'head'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
dojo.<span style="color: #660066;">create</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'link'</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span>rel<span style="color: #339933;">:</span> <span style="color: #3366CC;">'resource-package'</span><span style="color: #339933;">,</span> type<span style="color: #339933;">:</span> <span style="color: #3366CC;">'application/zip'</span><span style="color: #339933;">,</span> href<span style="color: #339933;">:</span> <span style="color: #3366CC;">'pkg3.zip'</span><span style="color: #339933;">,</span> contents<span style="color: #339933;">:</span> <span style="color: #3366CC;">'js/myModule.js; images/myPng.png'</span><span style="color: #339933;">,</span> head<span style="color: #339933;">,</span> <span style="color: #3366CC;">'last'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<h3>So. Can it be fixed?</h3>
<p>Of course.  But, frankly, I don&#8217;t really care.  For us dojo developers, all it&#8217;s going to help out with is images.  And since we&#8217;re using less and less images and more and more CSS3, images aren&#8217;t such a big deal going forward.   (border-image, border-radius, and gradient, FTW!)</p>
<p>But I guess, for image-heavy apps, there&#8217;s still a need.  So here&#8217;s how I&#8217;d fix it:</p>
<p>First of all, abandon that dumb-ass <code>packages</code> attribute.  It&#8217;s ugly, non-standard, and unworkable for the large apps that really need packaging.  Go back to the <code>&lt;link&gt;</code> tag.  That was a much better idea.</p>
<p>Or better yet, use the &lt;script&gt; tag.  (gasp)  And while you&#8217;re at it, fix the <code>defer</code> attribute so <em>I</em> can decide whether the package contains any resources that may need to invoke blocking.  (It could be a package of non-essential images, for instance.)</p>
<p>Hmmmm&#8230;. on second thought, the &lt;link&gt; may be semantically and syntactically better.  Therefore, maybe just add the <code>defer</code> attribute (and functionality) to the link tag?  </p>
<h3>Should it be fixed?</h3>
<p>The more I think about the proposed solutions, the more it seems they&#8217;re targeted toward trivial web apps/pages.  Unfortunately, it&#8217;s typically the larger, more sophisticated apps that need the performance boost.  </p>
<p>Therefore, I say, why bother?  </p>
<p>Instead, let&#8217;s find a way to package images and make dependency management a standard feature in javascript!</p>
<p>What do you say?  Am I missing something?  Do you have a better solution?  Please let me know in the comments!</p>
]]></content:encoded>
			<wfw:commentRss>http://unscriptable.com/2010/08/03/firefoxs-proposed-resource-packages-spec-sucks/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Deduplicate any array in Javascript</title>
		<link>http://unscriptable.com/2009/12/08/deduplicate-any-array-in-javascript/</link>
		<comments>http://unscriptable.com/2009/12/08/deduplicate-any-array-in-javascript/#comments</comments>
		<pubDate>Tue, 08 Dec 2009 05:04:30 +0000</pubDate>
		<dc:creator>John Hann</dc:creator>
				<category><![CDATA[dojo]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[performance]]></category>

		<guid isPermaLink="false">http://unscriptable.com/?p=467</guid>
		<description><![CDATA[As part of an ongoing project, I had to deduplicate a potentially large array of nodes.  ...  It seemed every other implementation used the hash map method and only worked on limited data types.  I hate writing the same code twice (unless it's to improve it), so I decided to write something that works with any data type.]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve neglected this blog lately.  My only excuse is that I am <em>very, very busy</em>! Not only have I been lucky enough to land a great opportunity working with some very bright jQuery Interactive Developers at <a href="http://www.molecular.com/">Molecular</a>, but I&#8217;ve also been working on <strong>something really big</strong>.  (More on that later!)</p>
<p>But despite being busy, I felt compelled to post this one. As part of the <strong>something really big</strong> project, I had to <a href="http://en.wikipedia.org/wiki/Data_deduplication">deduplicate</a> a potentially large array of nodes.  Dojo doesn&#8217;t have a built-in function for deduplication (a.k.a &#8220;deduping&#8221;).  How could it not?  Doesn&#8217;t everybody have to do this once in a while?  </p>
<p><em>I guess I&#8217;ll have to write one.  How hard could it be?</em><br />
<span id="more-467"></span><br />
It wasn&#8217;t because dojo didn&#8217;t implement a deduping method that I felt compelled.  No, it was the series of events after I wrote my own version.  Just after I finished it, one of those smart IDevs at Molecular shared his recent hash map-based implementations that worked only with numbers.  Then I noticed that jQuery has a deduping method, <code>unique()</code>.  However, it only deduplicates DOM Nodes.  </p>
<p>Finally, I ran across this blog <a href="http://dreaminginjavascript.wordpress.com/2008/08/22/eliminating-duplicates">post</a> that uses the hash-map method and works only on strings.  (Actually, it works on any objects that return unique values from their toString() methods, but that&#8217;s not as common as you&#8217;d think in Javascript. For example, object literals typically return &#8220;[Object object]&#8221; from the toString() method.)</p>
<p>It seemed every other implementation used the hash map method and only worked on limited data types.  I hate writing the same code twice (unless it&#8217;s to improve it), so I decided to write something that works with any data type.  </p>
<p><strong><em>One function to rule them all!</em> (No! Don&#8217;t even go there&#8230;!)</strong></p>
<p>I probably should have done some research before diving in, but that&#8217;s not how I roll.  (Where&#8217;s the challenge in that?)  From previous experience I already knew of at least two ways to do it: a) keeping a hash map of the values (hash map method), or b) pre-sorting the values.  The former method (hash map) seemed slower and more memory intensive, so I forged ahead with the second method (pre-sorting).</p>
<p>The pre-sort method works like this:</p>
<ol>
<li>sort the data items in the array</li>
<li>loop through the sorted data items:</li>
<li>compare each of the data items to the previous one</li>
<li>if the previous is the same as the current, don&#8217;t add the current item to the output array</li>
</ol>
<p><em>Simple enough!</em></p>
<p>Here&#8217;s the code using dojo to wrap the Javascript 1.6 Array iterators:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">    <span style="color: #003366; font-weight: bold;">function</span> dedup <span style="color: #009900;">&#40;</span><span style="color: #009966; font-style: italic;">/* Array */</span> array<span style="color: #339933;">,</span> <span style="color: #009966; font-style: italic;">/* Function */</span> compareFunc<span style="color: #339933;">,</span> <span style="color: #009966; font-style: italic;">/* Object? */</span> context<span style="color: #339933;">,</span> <span style="color: #009966; font-style: italic;">/* Boolean? */</span> preemptive<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #006600; font-style: italic;">//  summary: removes duplicate items from an array. compareFunc should behave</span>
        <span style="color: #006600; font-style: italic;">//      exactly like the lambda function used in array.sort(), returning:</span>
        <span style="color: #006600; font-style: italic;">//       0 - if the two items to compare are equivalent</span>
        <span style="color: #006600; font-style: italic;">//      -1 - if the first item should be sorted to an earlier position than the second</span>
        <span style="color: #006600; font-style: italic;">//       1 - if the first item should be sorted to a later position than the second</span>
        <span style="color: #006600; font-style: italic;">//      Returns an array with no duplicates.</span>
        <span style="color: #006600; font-style: italic;">//      Note: items found later in the array are favored over earlier items. This means</span>
        <span style="color: #006600; font-style: italic;">//      that if am earlier item is found to be a duplicate of an later item, it is not</span>
        <span style="color: #006600; font-style: italic;">//      included in the returned array.  You might ask, &quot;Who cares which one is favored?&quot;</span>
        <span style="color: #006600; font-style: italic;">//      Glad you asked! It depends upon how you define &quot;duplicate&quot;. If you wanted to</span>
        <span style="color: #006600; font-style: italic;">//      remove all nodes with duplicate ids, you could supply a compareFunc that inspected</span>
        <span style="color: #006600; font-style: italic;">//      node ids.  The nodes are not identical in this case, just the ids.</span>
        <span style="color: #006600; font-style: italic;">//      If you wish to favor the earlier items, set preemptive = true;</span>
        <span style="color: #006600; font-style: italic;">//      Note: undefined values are omitted from the output array.</span>
        <span style="color: #006600; font-style: italic;">//  array: Array - the array to be deduped</span>
        <span style="color: #006600; font-style: italic;">//  compareFunc: Function - see above</span>
        <span style="color: #006600; font-style: italic;">//  context: Object - context on which to run compareFunc (i.e. the &quot;this&quot; reference from</span>
        <span style="color: #006600; font-style: italic;">//      within compareFunc). defaults to null/window</span>
        <span style="color: #006600; font-style: italic;">//  preemptive: Boolean - set to true to favor earlier occuring items (see above)</span>
        <span style="color: #003366; font-weight: bold;">var</span> comparator <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #000066; font-weight: bold;">return</span> compareFunc.<span style="color: #660066;">apply</span><span style="color: #009900;">&#40;</span>context<span style="color: #339933;">,</span> arguments<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
            prev<span style="color: #339933;">,</span>
            keepers <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
        <span style="color: #006600; font-style: italic;">// by first sorting the array, we know that dups will be adjacent to each other</span>
        dojo.<span style="color: #660066;">forEach</span><span style="color: #009900;">&#40;</span>array.<span style="color: #660066;">sort</span><span style="color: #009900;">&#40;</span>comparator<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">item</span><span style="color: #339933;">,</span> pos<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">typeof</span> <span style="color: #000066; font-weight: bold;">item</span> <span style="color: #339933;">!=</span> <span style="color: #3366CC;">'undefined'</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">typeof</span> prev <span style="color: #339933;">==</span> <span style="color: #3366CC;">'undefined'</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                    keepers.<span style="color: #660066;">push</span><span style="color: #009900;">&#40;</span>pos<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                <span style="color: #009900;">&#125;</span>
                <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span>
                    <span style="color: #006600; font-style: italic;">// is the previous item different from this one?</span>
                    <span style="color: #003366; font-weight: bold;">var</span> eq <span style="color: #339933;">=</span> comparator<span style="color: #009900;">&#40;</span>prev<span style="color: #339933;">,</span> <span style="color: #000066; font-weight: bold;">item</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>
                    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>preemptive<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                        <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>eq<span style="color: #009900;">&#41;</span>
                            keepers.<span style="color: #660066;">push</span><span style="color: #009900;">&#40;</span>pos<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// add this one</span>
                    <span style="color: #009900;">&#125;</span>
                    <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span>
                        <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>eq<span style="color: #009900;">&#41;</span>
                            keepers.<span style="color: #660066;">pop</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// remove prev one</span>
                        keepers.<span style="color: #660066;">push</span><span style="color: #009900;">&#40;</span>pos<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// always add current one (it may be deleted in the next iteration)</span>
                    <span style="color: #009900;">&#125;</span>
                <span style="color: #009900;">&#125;</span>
                prev <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">item</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000066; font-weight: bold;">return</span> dojo.<span style="color: #660066;">map</span><span style="color: #009900;">&#40;</span>keepers<span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span>pos<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #000066; font-weight: bold;">return</span> array<span style="color: #009900;">&#91;</span>pos<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span></pre></div></div>

<p>The dedup() method requires an array (duh) and a comparison function (compareFunc).  The comparison function is exactly the same function you&#8217;d pass to sort an array.  Note that it&#8217;s run twice: once to sort the array and once to test if the previous value is the same as the current value.</p>
<p>The context parameter is useful if you need to pull in other data for compareFunc to do its job in the context of some object.  For even more control over which duplicate instances are kept, you can use the preemptive parameter.  Set this to true to keep items that occur earlier in the array.</p>
<p>I can see some people scratching their heads. <em>Why does it matter which item we keep if they&#8217;re duplicates of each other?</em>  Well, nobody said they had to be <em>exact</em> duplicates!  For instance, maybe you want to reduce a table&#8217;s rows to only the ones that have unique integer values in their first cell.</p>
<p>And here&#8217;s how you&#8217;d do that (error-checking omitted for brevity):</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> myDedupedRows <span style="color: #339933;">=</span> dedup<span style="color: #009900;">&#40;</span>myTable.<span style="color: #660066;">rows</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span>rowA<span style="color: #339933;">,</span> rowB<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #006600; font-style: italic;">// it's important to use a comparison that works correctly in Array sort() for best efficiency!</span>
    <span style="color: #000066; font-weight: bold;">return</span> parseInt<span style="color: #009900;">&#40;</span>rowA.<span style="color: #660066;">cells</span><span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span>.<span style="color: #660066;">innerHTML</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">-</span> parseInt<span style="color: #009900;">&#40;</span>rowB.<span style="color: #660066;">cells</span><span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span>.<span style="color: #660066;">innerHTML</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>That&#8217;s pretty simple if you are already comfortable with writing lambda functions for the sort method, of course.</p>
<p>Deduping numbers:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> uniques <span style="color: #339933;">=</span> dedup<span style="color: #009900;">&#40;</span>arrayOfNumberIDs<span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span>idA<span style="color: #339933;">,</span> idB<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">return</span> idA <span style="color: #339933;">-</span> idB<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Deduping object instances:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> uniques <span style="color: #339933;">=</span> dedup<span style="color: #009900;">&#40;</span>myObjects<span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span>objA<span style="color: #339933;">,</span> objB<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #006600; font-style: italic;">// this works for numbers, strings, dates... but don't mix types!</span>
    <span style="color: #000066; font-weight: bold;">return</span> objA.<span style="color: #660066;">keyProperty</span> <span style="color: #339933;">-</span> objB.<span style="color: #660066;">keyProperty</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Deduping object instances that have multiple key properties:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> uniques <span style="color: #339933;">=</span> dedup<span style="color: #009900;">&#40;</span>myObjects<span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span>objA<span style="color: #339933;">,</span> objB<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #003366; font-weight: bold;">var</span> test <span style="color: #339933;">=</span> objA.<span style="color: #660066;">keyProperty</span> <span style="color: #339933;">-</span> objB.<span style="color: #660066;">keyProperty</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>test <span style="color: #339933;">==</span> <span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #006600; font-style: italic;">// keyProperty is the same, so dig deeper</span>
        <span style="color: #000066; font-weight: bold;">return</span> objA.<span style="color: #660066;">altKey</span> <span style="color: #339933;">-</span> objB.<span style="color: #660066;">altKey</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">else</span>
        <span style="color: #000066; font-weight: bold;">return</span> test<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Deduping numbers the safe way:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> uniques <span style="color: #339933;">=</span> dedup<span style="color: #009900;">&#40;</span>arrayOfNumberIDs<span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span>idA<span style="color: #339933;">,</span> idB<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #006600; font-style: italic;">// force to numbers in case we have strings by accident</span>
    <span style="color: #000066; font-weight: bold;">return</span> parseFloat<span style="color: #009900;">&#40;</span>idA<span style="color: #009900;">&#41;</span> <span style="color: #339933;">-</span> parseFloat<span style="color: #009900;">&#40;</span>idB<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>At first glance, the pre-sort method looks more complex than the hash map methods, but it&#8217;s really not.  Once you take out the code that skips undefined values (like all good <a href="https://developer.mozilla.org/en/New_in_JavaScript_1.6">array iterators</a> should) and the code to allow the preemptive functionality, it&#8217;s only a line or two longer.</p>
<p>How about memory usage?  Hm.  My assumption that my method would use less memory wasn&#8217;t as accurate as I thought.  In the hash map methods, a temporary array and a hash-map of the non-redundant values are created.  In my pre-sort method, a complete copy of the original array and a copy of the deduped array are created.  This could go either way, depending on how large the original array is and on how Javascript engines internally manage hash maps (object literals, actually), but it&#8217;s likely that the pre-sort has a larger memory footprint.  (It&#8217;s likely that the Javascript engines create internal data structures to speed-up property look-ups on object literals.  However, it&#8217;s certain that the engines pre-allocate several kilobytes of space for array items. I&#8217;ll bet they allocate a minimum of 16kB per array created.)</p>
<p>Finally, I&#8217;m hesitant to claim any performance prizes, either.  I assume that since the compareFunc is run at least twice for each item in the array, it&#8217;s a performance bottleneck.  The hash map methods don&#8217;t do much in Javascript besides the loops.  The rest is run inside compiled code under the hood of the Javascript engine.  </p>
<p><strong>But maybe that&#8217;s the price for creating a function that dedups anything?</strong></p>
<p>I&#8217;m too <del datetime="2009-12-08T03:53:13+00:00">lazy</del> busy to test any of my assumptions, but if you are intrigued or bored, please have at it!  </p>
<p>And be sure to post any feedback! Did I miss something?  Did I make a stoopid mistake?   Can you write a version that falls back to the hash map method when using simple data types (and therefore doesn&#8217;t need compareFunc)?  </p>
<p>What? You don&#8217;t use dojo?!?! <img src='http://unscriptable.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />   A jQuery port should be brain-dead simple (s/dojo.forEach/$.each/ and s/dojo.map/$.map/).  Here&#8217;s a version that replaces the dojo calls with Javascript 1.6 array iterators.   (Note: Javascript 1.6 array iterators work in recent browsers only!)</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">    <span style="color: #003366; font-weight: bold;">function</span> dedup <span style="color: #009900;">&#40;</span>array<span style="color: #339933;">,</span> compareFunc<span style="color: #339933;">,</span> context<span style="color: #339933;">,</span> preemptive<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #003366; font-weight: bold;">var</span> comparator <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #000066; font-weight: bold;">return</span> compareFunc.<span style="color: #660066;">apply</span><span style="color: #009900;">&#40;</span>context<span style="color: #339933;">,</span> arguments<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
            prev<span style="color: #339933;">,</span>
            keepers <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
        array.<span style="color: #660066;">sort</span><span style="color: #009900;">&#40;</span>comparator<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">forEach</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">item</span><span style="color: #339933;">,</span> pos<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">typeof</span> <span style="color: #000066; font-weight: bold;">item</span> <span style="color: #339933;">!=</span> <span style="color: #3366CC;">'undefined'</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">typeof</span> prev <span style="color: #339933;">==</span> <span style="color: #3366CC;">'undefined'</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                    keepers.<span style="color: #660066;">push</span><span style="color: #009900;">&#40;</span>pos<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                <span style="color: #009900;">&#125;</span>
                <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span>
                    <span style="color: #003366; font-weight: bold;">var</span> eq <span style="color: #339933;">=</span> comparator<span style="color: #009900;">&#40;</span>prev<span style="color: #339933;">,</span> <span style="color: #000066; font-weight: bold;">item</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>
                    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>preemptive<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                        <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>eq<span style="color: #009900;">&#41;</span>
                            keepers.<span style="color: #660066;">push</span><span style="color: #009900;">&#40;</span>pos<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                    <span style="color: #009900;">&#125;</span>
                    <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span>
                        <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>eq<span style="color: #009900;">&#41;</span>
                            keepers.<span style="color: #660066;">pop</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                        keepers.<span style="color: #660066;">push</span><span style="color: #009900;">&#40;</span>pos<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                    <span style="color: #009900;">&#125;</span>
                <span style="color: #009900;">&#125;</span>
                prev <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">item</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000066; font-weight: bold;">return</span> keepers.<span style="color: #660066;">map</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span>pos<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #000066; font-weight: bold;">return</span> array<span style="color: #009900;">&#91;</span>pos<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://unscriptable.com/2009/12/08/deduplicate-any-array-in-javascript/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Hi-performance Javascript Tips #3: Less is More [Updated 2009-04-09]</title>
		<link>http://unscriptable.com/2009/04/09/hi-performance-javascript-tips-3-less-is-more/</link>
		<comments>http://unscriptable.com/2009/04/09/hi-performance-javascript-tips-3-less-is-more/#comments</comments>
		<pubDate>Thu, 09 Apr 2009 07:02:52 +0000</pubDate>
		<dc:creator>John Hann</dc:creator>
				<category><![CDATA[dojo]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[performance]]></category>

		<guid isPermaLink="false">http://unscriptable.com/?p=250</guid>
		<description><![CDATA[Sure, Javascript engines have matured. Safari's Nitro, Chrome's V8, Firefox's TraceMonkey, and Opera's Carackan all kick some serious butt.  (IE8's JScript, unfortunately, still sucks wind.)  However, routines written in C++ still run orders of magnitude faster in most cases.  ]]></description>
			<content:encoded><![CDATA[<p>This should really be Tip #1 since it&#8217;s the most critical of all.  Let me just say this as clearly as possible:</p>
<p><em><strong>Your fastest Javascript projects are the ones that have the least Javascript!</strong></em></p>
<p>Sure, Javascript engines have matured. Safari&#8217;s Nitro, Chrome&#8217;s V8, Firefox&#8217;s TraceMonkey, and Opera&#8217;s Carackan all kick some serious butt.  (IE8&#8242;s JScript, unfortunately, still sucks wind.)  However, routines written in C++ still run orders of magnitude faster in most cases.  </p>
<p><em>Don&#8217;t write Javascript to do something your browser already does at compiled-code speeds.</em><br />
<span id="more-250"></span><br />
Do you have any idea now many person-years of effort went into the regular expressions engine in your browser?  Tap into that resource!  </p>
<p>Here are some other resources you may be under-utilizing:</p>
<ul>
<li>Array.prototype.join <a href="http://unscriptable.com/index.php/2009/03/19/hi-performance-javascript-tip-2-revisited/">(example)</a></li>
<li>Array.prototype.slice <a href="http://unscriptable.com/index.php/2009/03/19/hi-performance-javascript-tips-1/">(example)</a></li>
<li>RegExp (many string-related optimizations!)</li>
<li><a href="https://developer.mozilla.org/En/New_in_JavaScript_1.6#Array_extras">Array iterators</a></li>
<li>DOM selectors (such as Acme (dojo) and Sizzle)</li>
</ul>
<p>I&#8217;ll dive into each of these in later blog posts, but here&#8217;s a teaser.  This example shows how to replace a relatively slow <code>while</code> loop with an Array iterator.</p>
<p>Our while loop:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> nodes <span style="color: #339933;">=</span> dojo.<span style="color: #660066;">query</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'*[title]'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #006600; font-style: italic;">// using dojo just as an example</span>
    found<span style="color: #339933;">,</span> <span style="color: #006600; font-style: italic;">// we're looking for a particular node and will store it here</span>
    len <span style="color: #339933;">=</span> nodes.<span style="color: #660066;">length</span><span style="color: #339933;">,</span> <span style="color: #006600; font-style: italic;">// performance boost to grab this outside of the loop</span>
    i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// just an iteration counter</span>
&nbsp;
<span style="color: #000066; font-weight: bold;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>found <span style="color: #339933;">&amp;&amp;</span> i <span style="color: #339933;">&lt;</span> len<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #006600; font-style: italic;">// found will remain false until we find our node</span>
    found <span style="color: #339933;">=</span> nodes<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span>.<span style="color: #660066;">getAttribute</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'title'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">indexOf</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'Loading'</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&gt;=</span> <span style="color: #CC0000;">0</span> <span style="color: #339933;">&amp;&amp;</span> nodes<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
    i<span style="color: #339933;">++;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>found<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #006600; font-style: italic;">// do something with &lt;&lt;found&gt;&gt; here</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>That&#8217;s not a bad while loop.  You&#8217;ll notice that I am overloading the meaning of the <code>found</code> variable.  <em>This is an acceptable practice in high-performance situations as long as the code is well-documented to prevent confusion.</em></p>
<p>Here&#8217;s the same loop utilizing the Array iterator <code>some</code> wrapped by dojo NodeList&#8217;s <code>some</code> method:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> found<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// we're looking for a particular node and will store it here</span>
dojo.<span style="color: #660066;">query</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'*[title]'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">some</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span>node<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #006600; font-style: italic;">// found will remain false until we find our node</span>
    found <span style="color: #339933;">=</span> node.<span style="color: #660066;">getAttribute</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'title'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">indexOf</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'Loading'</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&gt;=</span> <span style="color: #CC0000;">0</span> <span style="color: #339933;">&amp;&amp;</span> node<span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">return</span> found<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>found<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #006600; font-style: italic;">// do something with &lt;&lt;found&gt;&gt; here</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Leaner!  Faster!  Sexier!</p>
<hr/>
<p>OK.  Here&#8217;s the point where I scratch my head.  I just ran both of these against <a href="http://dojocampus.org/">dojocampus.org</a> in FF 3.1 and Safari 4.0.  To my surprise, the <code>while</code> loop performed slightly better than the <code>some</code> (1ms difference).  I removed the <code>[title]</code> attribute from the query selector to get some better test data.  Same story.</p>
<p>There was a big difference in IE7, though.</p>
<p>I guess the latest Javascript engines really do kick butt!!!!</p>
<hr/>
<strong>Update 2009-04-09:</strong></p>
<p>My best guess is that the NodeList that <code>dojo.query</code> returns is slowing our example code.  A NodeList is not a true array.  It is an Array-like object, which simply means it exposes its list of items as properties whose names are Cardinal number and also exposes a length property.  So I created a quick and dirty test on a true array:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// using some</span>
<span style="color: #003366; font-weight: bold;">var</span> a <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
<span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> <span style="color: #CC0000;">100000</span><span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> a<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Date<span style="color: #009900;">&#40;</span><span style="color: #CC0000;">2009</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">,</span> i<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> found<span style="color: #339933;">,</span> s <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Date<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
a.<span style="color: #660066;">some</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">item</span><span style="color: #339933;">,</span> i<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    found <span style="color: #339933;">=</span> i <span style="color: #339933;">==</span> <span style="color: #CC0000;">99999</span> <span style="color: #339933;">?</span> <span style="color: #000066; font-weight: bold;">item</span> <span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">return</span> found<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">new</span> Date<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">-</span> s<span style="color: #339933;">,</span> found<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// using while</span>
<span style="color: #003366; font-weight: bold;">var</span> len <span style="color: #339933;">=</span> a.<span style="color: #660066;">length</span><span style="color: #339933;">,</span> found <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">,</span> s <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Date<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>
<span style="color: #000066; font-weight: bold;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>found <span style="color: #339933;">&amp;&amp;</span> i <span style="color: #339933;">&lt;</span> len<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
   found <span style="color: #339933;">=</span> i <span style="color: #339933;">==</span> <span style="color: #CC0000;">99999</span> <span style="color: #339933;">?</span> a<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span> <span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">;</span>
    i<span style="color: #339933;">++;</span>
<span style="color: #009900;">&#125;</span>
console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">new</span> Date<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">-</span> s<span style="color: #339933;">,</span> found<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>The results showed that some ran about 17% faster in Firefox 3.0, 32% faster in Firefox 3.1beta, and 43% faster in Safari 4.0beta.  Of course, the code inside our loop is very simple.  More complex code will consume a larger slice of the total time and will therefore make the effect of the loop mechanism less important.  </p>
<p>Moral of the story: to get the best performance when looping through real arrays (rather than Nodelists or Array-like objects), use the Array iterators or their browser-safe counterparts in the major libraries.  When using NodeLists, either method works great as long as you&#8217;ve tuned your loop correctly.  (Sounds like another blog post&#8230;)</p>
<p>I&#8217;d like to hear from you!  What library do you use and how does it handle Array iterators?</p>
]]></content:encoded>
			<wfw:commentRss>http://unscriptable.com/2009/04/09/hi-performance-javascript-tips-3-less-is-more/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Debouncing Javascript Methods</title>
		<link>http://unscriptable.com/2009/03/20/debouncing-javascript-methods/</link>
		<comments>http://unscriptable.com/2009/03/20/debouncing-javascript-methods/#comments</comments>
		<pubDate>Fri, 20 Mar 2009 07:21:21 +0000</pubDate>
		<dc:creator>John Hann</dc:creator>
				<category><![CDATA[dojo]]></category>
		<category><![CDATA[Event Handling]]></category>
		<category><![CDATA[Javascript]]></category>

		<guid isPermaLink="false">http://unscriptable.com/?p=7</guid>
		<description><![CDATA[... a user could simply lean on the Tab key to navigate from one end of the form to the other.  If the user were lucky enough to be on a fast network connection and had a fast enough browser, this would go fairly smoothly.  However, the server would get absolutely hammered by all of the XHR requests necessary to populate the side-bar!  ]]></description>
			<content:encoded><![CDATA[<p>Back in 2006, I was the lead front-end architect for a mission-critical Web 2.0 application.  Yah-yah, aren&#8217;t they all mission-critical?  Yes, but this one really was critical since it was one of those make-or-break moments for the product.  What made this project really interesting were the unrealistic expectations the product managers had of web apps.  </p>
<p>Sometimes, pressure like this can lead to creativity and innovation.  On this occasion, it helped me reach back in to my electrical engineering coursework to apply a hardware concept to software programming.<br />
<span id="more-698"></span><br />
Just imagine this:</p>
<ol>
<li>You are tasked to write the entire Javascript-based framework from scratch, including the core functions (inheritance, declarations, event connections), DOM manipulation and querying, a widget framework, MVC, drag-and-drop, and dozens of custom widgets to boot.</li>
<li>You are given unintuitive and un-web-like requirements to ensure that the app allowed customers to adhere to strict FDA regulations.</li>
<li>The product managers had no experience with web app development so they designed the requirements for a Windows application.  You know: modal dialogs, instant retrieval of large amounts of data (as if it were coming straight from the disk), workflows that depended on sequenced calls to/from the back-end systems, etc.</li>
</ol>
<p>Oh, and did I mention there was a deadline and only two of us were hired to code the entire UI side of the project?  </p>
<p>Well, I am always up for a challenge, especially if somebody says, &#8220;It can&#8217;t be done&#8221;.  So needless to say, I had to really use my brain on this project.  </p>
<p>One of the more interesting requirements was to show the user a summary side-bar of information pertaining to the current field (i.e. the input element that had focus).  This side-bar information could be from several kilobytes to more than 100 kB.  The data had to be fetched via XHR from the back-end and displayed each time the user entered a new field.  </p>
<p>This presented a major problem if the user was keyboard-oriented and preferred to use the Tab key to move from field to field.  There could be hundreds of fields on the screen, and a user could simply lean on the Tab key to navigate from one end of the form to the other.  If the user were lucky enough to be on a fast network connection and had a fast enough browser, this would go fairly smoothly.  However, the server would get absolutely hammered by all of the XHR requests necessary to populate the side-bar!  </p>
<p>Luckily, I had handled this situation several times before.  A simple setTimeout and a few state variables fixes this problem fairly easily.  But there were several of these situations in this project, and I wanted to build something reusable.  </p>
<p>The more I thought about it, the more it felt like <a href="http://en.wikipedia.org/wiki/Switch#Contact_bounce">contact debouncing</a>.  Debouncing means to coalesce several temporally close signals into one signal.  For example, your computer keyboard does this.  Every time you hit a key, the contacts actually bounce a few times, causing several signals to be sent to the circuitry.  The circuitry determines that the bouncing has ended when no bounces are detected within a certain period (the &#8220;detection period&#8221;).  Since people can&#8217;t really type faster than roughly 10 keys per second, any signals happening within 100 msec of each other, for example, are likely part of the same key press.  (In practice, you should at least halve this, so about 50 msec for our keyboard example.  I have no idea what keyboards really use, by the way.  This is just an illustration.)</p>
<h2>Debouncing != Throttling</h2>
<p>Whenever I bring up the concept of debouncing, developers try to cast it as just a means of throttling.  But that&#8217;s not true at all.  Throttling is the reduction in rate of a repeating event.  Throttling is good for reducing mousemove events to a lesser, manageable rate, for instance.</p>
<p>Debouncing is quite more precise.  Debouncing ensures that exactly one signal is sent for an event that may be happening several times &mdash; or even several hundreds of times over an extended period.  As long as the events are occurring fast enough to happen at least once in every detection period, the signal will not be sent!  </p>
<p>Let&#8217;s relate this back to our keyboard-oriented user and our huge set of form fields.  Throttling here would certainly help.  We could reduce the number of XHR requests to a lower rate than the computer&#8217;s key repeat rate for sure!  However, we&#8217;d still be fetching from the back-end more times than necessary, and the occasional re-rendering of the fetched data could temporarily freeze up the browser, deteriorating the user experience.  </p>
<p>Debouncing on the other hand could better detect when the user stopped leaning on the keyboard and had arrived at their destination.  It&#8217;s certainly not perfect.  The user still may overshoot their destination, hesitate, and back-track, causing enough delay for the debounce detection period to expire.  However, our tests showed that debouncing did a much better job of reducing XHR requests than throttling.  </p>
<h2>Implementation</h2>
<p>The original debounce method was rather large and clunky.  I consider it a prototype.  A proof of concept.  I ended up needing debouncing a few times since that project and rewrote it each time, trying to improve it.  I&#8217;ve finally devised something that feels good enough to share.  </p>
<p>The latest rendition takes two parameters: the detection period (&#8220;threshold&#8221;) and a Boolean indicating whether the signal should happen at the beginning of the detection period (true) or the end (&#8220;execAsap&#8221;).</p>
<p>Here it is:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">Function</span>.<span style="color: #660066;">prototype</span>.<span style="color: #660066;">debounce</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span>threshold<span style="color: #339933;">,</span> execAsap<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #003366; font-weight: bold;">var</span> func <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span><span style="color: #339933;">,</span> <span style="color: #006600; font-style: italic;">// reference to original function</span>
        timeout<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// handle to setTimeout async task (detection period)</span>
    <span style="color: #006600; font-style: italic;">// return the new debounced function which executes the original function only once</span>
    <span style="color: #006600; font-style: italic;">// until the detection period expires</span>
    <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #003366; font-weight: bold;">function</span> debounced <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #003366; font-weight: bold;">var</span> obj <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span><span style="color: #339933;">,</span> <span style="color: #006600; font-style: italic;">// reference to original context object</span>
            args <span style="color: #339933;">=</span> arguments<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// arguments at execution time</span>
        <span style="color: #006600; font-style: italic;">// this is the detection function. it will be executed if/when the threshold expires</span>
        <span style="color: #003366; font-weight: bold;">function</span> delayed <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #006600; font-style: italic;">// if we're executing at the end of the detection period</span>
            <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>execAsap<span style="color: #009900;">&#41;</span>
                func.<span style="color: #660066;">apply</span><span style="color: #009900;">&#40;</span>obj<span style="color: #339933;">,</span> args<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// execute now</span>
            <span style="color: #006600; font-style: italic;">// clear timeout handle</span>
            timeout <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">;</span> 
        <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
        <span style="color: #006600; font-style: italic;">// stop any current detection period</span>
        <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>timeout<span style="color: #009900;">&#41;</span>
            clearTimeout<span style="color: #009900;">&#40;</span>timeout<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #006600; font-style: italic;">// otherwise, if we're not already waiting and we're executing at the beginning of the detection period</span>
        <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>execAsap<span style="color: #009900;">&#41;</span>
            func.<span style="color: #660066;">apply</span><span style="color: #009900;">&#40;</span>obj<span style="color: #339933;">,</span> args<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// execute now</span>
        <span style="color: #006600; font-style: italic;">// reset the detection period</span>
        timeout <span style="color: #339933;">=</span> setTimeout<span style="color: #009900;">&#40;</span>delayed<span style="color: #339933;">,</span> threshold <span style="color: #339933;">||</span> <span style="color: #CC0000;">100</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>It works by issuing a setTimeout at the specified detection period.  Each time the function is called, the setTimeout is canceled and issued again.  This serves as our detection mechanism, but using reverse logic.  If/when the setTimeout executes, we know that our function was not called within the detection period.</p>
<p>Wow. It looks rather large with all of those comments.  Here is a version without the comments:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">Function</span>.<span style="color: #660066;">prototype</span>.<span style="color: #660066;">debounce</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span>threshold<span style="color: #339933;">,</span> execAsap<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
    <span style="color: #003366; font-weight: bold;">var</span> func <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span><span style="color: #339933;">,</span> timeout<span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #003366; font-weight: bold;">function</span> debounced <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #003366; font-weight: bold;">var</span> obj <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span><span style="color: #339933;">,</span> args <span style="color: #339933;">=</span> arguments<span style="color: #339933;">;</span>
        <span style="color: #003366; font-weight: bold;">function</span> delayed <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>execAsap<span style="color: #009900;">&#41;</span>
                func.<span style="color: #660066;">apply</span><span style="color: #009900;">&#40;</span>obj<span style="color: #339933;">,</span> args<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            timeout <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">;</span> 
        <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>timeout<span style="color: #009900;">&#41;</span>
            clearTimeout<span style="color: #009900;">&#40;</span>timeout<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>execAsap<span style="color: #009900;">&#41;</span>
            func.<span style="color: #660066;">apply</span><span style="color: #009900;">&#40;</span>obj<span style="color: #339933;">,</span> args<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        timeout <span style="color: #339933;">=</span> setTimeout<span style="color: #009900;">&#40;</span>delayed<span style="color: #339933;">,</span> threshold <span style="color: #339933;">||</span> <span style="color: #CC0000;">100</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>If you prefer not to augment the native objects, here&#8217;s a stand-alone version:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> debounce <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span>func<span style="color: #339933;">,</span> threshold<span style="color: #339933;">,</span> execAsap<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
    <span style="color: #003366; font-weight: bold;">var</span> timeout<span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #003366; font-weight: bold;">function</span> debounced <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #003366; font-weight: bold;">var</span> obj <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span><span style="color: #339933;">,</span> args <span style="color: #339933;">=</span> arguments<span style="color: #339933;">;</span>
        <span style="color: #003366; font-weight: bold;">function</span> delayed <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>execAsap<span style="color: #009900;">&#41;</span>
                func.<span style="color: #660066;">apply</span><span style="color: #009900;">&#40;</span>obj<span style="color: #339933;">,</span> args<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            timeout <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">;</span> 
        <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>timeout<span style="color: #009900;">&#41;</span>
            clearTimeout<span style="color: #009900;">&#40;</span>timeout<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>execAsap<span style="color: #009900;">&#41;</span>
            func.<span style="color: #660066;">apply</span><span style="color: #009900;">&#40;</span>obj<span style="color: #339933;">,</span> args<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        timeout <span style="color: #339933;">=</span> setTimeout<span style="color: #009900;">&#40;</span>delayed<span style="color: #339933;">,</span> threshold <span style="color: #339933;">||</span> <span style="color: #CC0000;">100</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Example uses:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// using debounce in a constructor or initialization function to debounce </span>
<span style="color: #006600; font-style: italic;">// focus events for a widget (onFocus is the original handler):</span>
    <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">debouncedOnFocus</span> <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #000066;">onFocus</span>.<span style="color: #660066;">debounce</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">500</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">inputNode</span>.<span style="color: #660066;">addEventListener</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'focus'</span><span style="color: #339933;">,</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">debouncedOnFocus</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
&nbsp;
<span style="color: #006600; font-style: italic;">// to coordinate the debounce of a method for all objects of a certain class, do this:</span>
MyClass.<span style="color: #660066;">prototype</span>.<span style="color: #660066;">someMethod</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #009966; font-style: italic;">/* do something here, but only once */</span>
<span style="color: #009900;">&#125;</span>.<span style="color: #660066;">debounce</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">100</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// execute at start and use a 100 msec detection period</span>
&nbsp;
&nbsp;
<span style="color: #006600; font-style: italic;">// the dojo way to coordinate the debounce of a method for all objects of a certain class</span>
<span style="color: #006600; font-style: italic;">// (using the stand-alone version)</span>
dojo.<span style="color: #660066;">declare</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'MyClass'</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">// other members go here</span>
&nbsp;
    someMethod<span style="color: #339933;">:</span> debounce<span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #009966; font-style: italic;">/* do something here, but only once */</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">100</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// execute at start and use a 100 msec detection period</span>
&nbsp;
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
&nbsp;
<span style="color: #006600; font-style: italic;">// wait until the user is done moving the mouse, then execute</span>
<span style="color: #006600; font-style: italic;">// (using the stand-alone version)</span>
document.<span style="color: #660066;">onmousemove</span> <span style="color: #339933;">=</span> debounce<span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span>e<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #009966; font-style: italic;">/* do something here, but only once after mouse cursor stops */</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">250</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p><strong>Let me know if you find this useful in <em>your</em> projects!</strong></p>
<p>P.S.  The mission-critical project was a success!</p>
]]></content:encoded>
			<wfw:commentRss>http://unscriptable.com/2009/03/20/debouncing-javascript-methods/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
	</channel>
</rss>

