<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title></title>
    <link href="http://artisanofcode.com/atom.xml" rel="self" />
    <link href="http://artisanofcode.com/blog/"/>
    <updated>2012-05-13T11:49:35Z</updated>
    <id>urn:uuid:72c1f5fc-5a55-11e1-b092-1093e9024776</id>
    <entry>
        <title type="html">More is Less</title>
        <author><name>Daniel Knell</name></author>
        <link href="http://artisanofcode.com/archive/2011/04/more-less"/>
        <updated>2011-04-29T00:00:00Z</updated>
        <published>2011-04-29T00:00:00Z</published>
        <id>urn:uuid:38f0b962-5a4b-11e1-abfe-1093e9024776</id>
        <category scheme="/archive/tags" term="javascript" label="Javascript" />
        <content type="html">
        &lt;p&gt;When adding JavaScript to a small site or blog, most web developers will
instinctively reach for jQuery, however, most of the time the issues they are
trying to resolve could had easily been fixed, in far less than the &lt;span class=&#34;caps&#34;&gt;214KB&lt;/span&gt; jQuery
adds to their uncompressed&amp;nbsp;page weight.&lt;/p&gt;
&lt;h2 id=&#34;dom&#34;&gt;&lt;abbr title=&#34;Document Object Model&#34;&gt;&lt;span class=&#34;caps&#34;&gt;DOM&lt;/span&gt;&lt;/abbr&gt;&lt;/h2&gt;
&lt;p&gt;A large amount of the &lt;abbr title=&#34;Cascading Style Sheets&#34;&gt;&lt;span class=&#34;caps&#34;&gt;CSS&lt;/span&gt;&lt;/abbr&gt; selectors used in jQuery scripts consist of a single
id, tag, or class name, and this is just as easily accomplished with native
&lt;abbr title=&#34;Application Programming Interface&#34;&gt;&lt;span class=&#34;caps&#34;&gt;API&lt;/span&gt;&lt;/abbr&gt;’s.&lt;/p&gt;
&lt;p&gt;Todays browsers have near perfect support for getElementById,
getElementByTagName, and getElementByClassName, with the latter being
unsupported but easily emulated in older versions of&amp;nbsp;Internet Explorer.&lt;/p&gt;
&lt;div class=&#34;codehilite&#34;&gt;&lt;pre&gt;&lt;span class=&#34;kd&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;getElementsByClassName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;el&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;className&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;el&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;getElementsByClassName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;el&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;getElementsByClassName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;className&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;else&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
        &lt;span class=&#34;kd&#34;&gt;var&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;elements&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;el&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;all&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;?&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;el&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;all&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;el&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;getElementsByTagName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;quot;*&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;
            &lt;span class=&#34;nx&#34;&gt;regex&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;RegExp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;(^|\\s)&amp;#39;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;className&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;(\\s|$)&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;
            &lt;span class=&#34;nx&#34;&gt;result&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[];&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;var&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;i&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;l&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;elements&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;length&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;i&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;l&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;++&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
            &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;regex&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;test&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;element&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;].&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;className&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
                &lt;span class=&#34;nx&#34;&gt;result&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;push&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;element&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]);&lt;/span&gt;
            &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;result&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Admittedly this does not look as aesthetically pleasing as the jQuery &lt;abbr title=&#34;Domain Specific Language&#34;&gt;&lt;span class=&#34;caps&#34;&gt;DSL&lt;/span&gt;&lt;/abbr&gt; but it
is no any&amp;nbsp;less readable.&lt;/p&gt;
&lt;div class=&#34;codehilite&#34;&gt;&lt;pre&gt;&lt;span class=&#34;c1&#34;&gt;// before&lt;/span&gt;
&lt;span class=&#34;nx&#34;&gt;$&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;quot;#status&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;html&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;status&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;// after&lt;/span&gt;
&lt;span class=&#34;nb&#34;&gt;document&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;getElementById&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;quot;status&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;innerHTML&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;status&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;h2 id=&#34;events&#34;&gt;Events&lt;/h2&gt;
&lt;p&gt;Once we have our &lt;abbr title=&#34;Document Object Model&#34;&gt;&lt;span class=&#34;caps&#34;&gt;DOM&lt;/span&gt;&lt;/abbr&gt; elements the next step is generally to bind events to them,
this is not consistent across browsers, but fortunately the problem was solved a
long time ago, and a well established polyfill can be found in the addEvent
method graciously hosted by the QuirksMode Blog&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; rel=&#34;footnote&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;div class=&#34;codehilite&#34;&gt;&lt;pre&gt;&lt;span class=&#34;c1&#34;&gt;// before&lt;/span&gt;
&lt;span class=&#34;nx&#34;&gt;$&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;buttonElement&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;click&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;nx&#34;&gt;alert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;$&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;this&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;html&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;());&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;});&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;// after&lt;/span&gt;
&lt;span class=&#34;nx&#34;&gt;addEvent&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;buttonElement&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;quot;click&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kd&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;nx&#34;&gt;alert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;this&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;innerHTML&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;});&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;When it comes to events, it turns out the jQuery &lt;abbr title=&#34;Domain Specific Language&#34;&gt;&lt;span class=&#34;caps&#34;&gt;DSL&lt;/span&gt;&lt;/abbr&gt; does not really add much on
top of the&amp;nbsp;existing solutions.&lt;/p&gt;
&lt;h2 id=&#34;ajax&#34;&gt;&lt;abbr title=&#34;Asynchronous JavaScript and XML&#34;&gt;&lt;span class=&#34;caps&#34;&gt;AJAX&lt;/span&gt;&lt;/abbr&gt;&lt;/h2&gt;
&lt;p&gt;Normalizing the XMLHttpRequest object across browsers is also a fairly easy job,
and there are countless blog posts dedicated to the subject, including a simple
solution by &lt;span class=&#34;caps&#34;&gt;PPK&lt;/span&gt;&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; rel=&#34;footnote&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;div class=&#34;codehilite&#34;&gt;&lt;pre&gt;&lt;span class=&#34;c1&#34;&gt;// before&lt;/span&gt;
&lt;span class=&#34;nx&#34;&gt;$&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;quot;/ajax.php&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kd&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;kd&#34;&gt;var&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;el&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;$&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;quot;#content&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
    &lt;span class=&#34;nx&#34;&gt;el&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;html&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;});&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;// after&lt;/span&gt;
&lt;span class=&#34;nx&#34;&gt;sendRequest&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;/ajax.php&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kd&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;req&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;kd&#34;&gt;var&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;el&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;document&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;getElementById&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;quot;content&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
    &lt;span class=&#34;nx&#34;&gt;el&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;innerHTML&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;req&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;responseText&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;});&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Again the jQuery &lt;abbr title=&#34;Domain Specific Language&#34;&gt;&lt;span class=&#34;caps&#34;&gt;DSL&lt;/span&gt;&lt;/abbr&gt; adds little to the existing solutions, with the existing
solutions adding very little to the&amp;nbsp;page weight.&lt;/p&gt;
&lt;h2 id=&#34;effects&#34;&gt;Effects&lt;/h2&gt;
&lt;p&gt;Depending on the target audience and the relevance of the effects, one could
argue that they are better implemented as &lt;abbr title=&#34;Cascading Style Sheets Level 3&#34;&gt;&lt;span class=&#34;caps&#34;&gt;CSS3&lt;/span&gt;&lt;/abbr&gt; transitions and transformations,
leaving the slower browsers such as &lt;abbr title=&#34;Internet Explorer&#34;&gt;&lt;span class=&#34;caps&#34;&gt;IE&lt;/span&gt;&lt;/abbr&gt; with a fast but less rich experience, but
if you must have animations in &lt;abbr title=&#34;Internet Explorer&#34;&gt;&lt;span class=&#34;caps&#34;&gt;IE&lt;/span&gt;&lt;/abbr&gt;, then this is one area where doing it yourself
is probably a bad idea, and is best left to an effects&amp;nbsp;library.&lt;/p&gt;
&lt;h2 id=&#34;conclusions&#34;&gt;Conclusions&lt;/h2&gt;
&lt;p&gt;Before reaching for a library, we should fully evaluate the problem and ask
ourselves whether the said library will justify its self? Are there more
appropriate choices? And do we need a library&amp;nbsp;at all?&lt;/p&gt;
&lt;div class=&#34;footnote&#34;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;&lt;a href=&#34;http://www.quirksmode.org/blog/archives/2005/10/_and_the_winner_1.html&#34;&gt;The New addEvent Method&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:1&#34; rev=&#34;footnote&#34; title=&#34;Jump back to footnote 1 in the text&#34;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;&lt;a href=&#34;http://www.quirksmode.org/js/xmlhttp.html&#34;&gt;XMLHttpRequest Functions&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:2&#34; rev=&#34;footnote&#34; title=&#34;Jump back to footnote 2 in the text&#34;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
        </content>
    </entry>
    <entry>
        <title type="html">No More Clever JavaScript</title>
        <author><name>Daniel Knell</name></author>
        <link href="http://artisanofcode.com/archive/2011/01/no-more-clever-javascript"/>
        <updated>2011-01-01T00:00:00Z</updated>
        <published>2011-01-01T00:00:00Z</published>
        <id>urn:uuid:3120d762-5a4b-11e1-a5df-1093e9024776</id>
        <category scheme="/archive/tags" term="javascript" label="Javascript" />
        <content type="html">
        &lt;p&gt;There is much clever JavaScript out there now days, and maybe it&amp;#8217;s the python
developer in me, but I don&amp;#8217;t like it one bit. I truly believe that we should
strive for simplicity, elegance, and above all readability in our&amp;nbsp;code.&lt;/p&gt;
&lt;h2 id=&#34;check-your-ego-at-the-door&#34;&gt;Check your Ego at the&amp;nbsp;Door&lt;/h2&gt;
&lt;p&gt;As developers we all have egos to satisfy and it can be hard not to show off,
but it seems we often forget that it is harder to write simple code than it is
to try to be clever. We also seem to forget that code needs to be maintained,
and just because something makes sense to us now, does not mean it will do so
in the future, or to&amp;nbsp;others.&lt;/p&gt;
&lt;p&gt;If popular knowledge is to be believed, then debugging code is twice as hard as
writing it, should this ring true, what chance do our more junior colleagues
have when they are tasked with its future&amp;nbsp;maintenance?&lt;/p&gt;
&lt;p&gt;Most of the cleverness seems to stem from efforts to either reduce lines of
code, or to make small micro optimisations, neither of these provide enough of
a benefit to warrant a decrease in readability. Minification yields a far more
significant decrease in size, and the speed of modern JavaScript interpreters
&amp;#8212; as well as the hardware they run on &amp;#8212; is increasing at a rate far
surpassing any improvements in our ability to debug&amp;nbsp;code.&lt;/p&gt;
&lt;p&gt;Do we want our legacy to be one of torturous debugging or a joyful experience
extending that which we leave behind? Which would you rather find at your next&amp;nbsp;project?&lt;/p&gt;
&lt;h2 id=&#34;the-plea&#34;&gt;The&amp;nbsp;Plea&lt;/h2&gt;
&lt;p&gt;JavaScript is finally starting to gain recognition, moving beyond the browser,
into everything from game engines to web servers, now is our chance to define
ourselves, lets try not to screw it&amp;nbsp;up.&lt;/p&gt;
&lt;p&gt;So, can we quit with the clever stuff now, and instead focus on creating
simple, elegant, and above all readable&amp;nbsp;code?&lt;/p&gt;
        </content>
    </entry>
    <entry>
        <title type="html">An Event Driven Frontend</title>
        <author><name>Daniel Knell</name></author>
        <link href="http://artisanofcode.com/archive/2010/12/event-driven-frontend"/>
        <updated>2010-12-15T00:00:00Z</updated>
        <published>2010-12-15T00:00:00Z</published>
        <id>urn:uuid:2788cd68-5a4b-11e1-b767-1093e9024776</id>
        <category scheme="/archive/tags" term="javascript" label="Javascript" />
        <content type="html">
        &lt;p&gt;After spending the last year with node.js I have come to appreciate
JavaScript&amp;#8217;s strength as an event driven language, and yet in the browser,
beyond binding callbacks to &lt;abbr title=&#34;Document Object Model&#34;&gt;&lt;span class=&#34;caps&#34;&gt;DOM&lt;/span&gt;&lt;/abbr&gt; events and &lt;abbr title=&#34;Asynchronous JavaScript and XML&#34;&gt;&lt;span class=&#34;caps&#34;&gt;AJAX&lt;/span&gt;&lt;/abbr&gt; requests, the majority of
front-end code seems to be developed in a mostly procedural&amp;nbsp;way.&lt;/p&gt;
&lt;p&gt;Recently when faced with taking on a codebase that had grown unmanageable due
to the procedural model that had been employed thus far, I began by refactoring
the code around a central event dispatcher, allowing many of the large methods
&amp;#8212; that had previously been created &amp;#8212; to be broken down into smaller more
loosely coupled&amp;nbsp;pieces.&lt;/p&gt;
&lt;h2 id=&#34;benefits&#34;&gt;Benefits&lt;/h2&gt;
&lt;p&gt;By introducing an asynchronous model to the code, we were able to break much of
it into smaller more maintainable pieces, including a clean break between
presentation &amp;#8212; such as animations or manipulating the &lt;abbr title=&#34;Document Object Model&#34;&gt;&lt;span class=&#34;caps&#34;&gt;DOM&lt;/span&gt;&lt;/abbr&gt; &amp;#8212; and the business
logic, involving &lt;abbr title=&#34;Asynchronous JavaScript and XML&#34;&gt;&lt;span class=&#34;caps&#34;&gt;AJAX&lt;/span&gt;&lt;/abbr&gt; requests and &lt;abbr title=&#34;Application Programming Interface&#34;&gt;&lt;span class=&#34;caps&#34;&gt;API&lt;/span&gt;&lt;/abbr&gt;&amp;nbsp;calls.&lt;/p&gt;
&lt;p&gt;A more loosely coupled system also helped to simplify the development, allowing
smaller related sections to be developed independently and by different members
of the&amp;nbsp;team.&lt;/p&gt;
&lt;h2 id=&#34;solutions&#34;&gt;Solutions&lt;/h2&gt;
&lt;p&gt;&lt;abbr title=&#34;Yahoo User Interface Version 3&#34;&gt;&lt;span class=&#34;caps&#34;&gt;YUI3&lt;/span&gt;&lt;/abbr&gt; has custom event handling baked in&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; rel=&#34;footnote&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;, and I highly suggest &lt;abbr title=&#34;Yahoo User Interface&#34;&gt;&lt;span class=&#34;caps&#34;&gt;YUI&lt;/span&gt;&lt;/abbr&gt; as a
framework for any large scale javascript&amp;nbsp;project.&lt;/p&gt;
&lt;p&gt;The same technique could be created using jQuery custom events on the document element, although it would be advisable to use one of the dedicated plugins available such as jQuery pubsub by Peter Higgins&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; rel=&#34;footnote&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;There are also library agnostic implementations such as the brilliant PubSubJS&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; rel=&#34;footnote&#34;&gt;3&lt;/a&gt;&lt;/sup&gt; by Morgan Roderick &amp;#8212; whom I was fortunate enough to speak with at the fullfrontal&lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; rel=&#34;footnote&#34;&gt;4&lt;/a&gt;&lt;/sup&gt; pre conference drinks earlier this month &amp;#8212; and after reading through the code on github I can highly recommend his&amp;nbsp;library.&lt;/p&gt;
&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;The exact implementation of this concept does not matter &amp;#8212; and will vary
massively depending on your choices of framework and libraries &amp;#8212; but it should
be seriously considered for any medium to large scale javascript&amp;nbsp;project.&lt;/p&gt;
&lt;div class=&#34;footnote&#34;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;&lt;a href=&#34;http://developer.yahoo.com/yui/3/event/#customevent&#34;&gt;&lt;abbr title=&#34;Yahoo User Interface Version 3&#34;&gt;&lt;abbr title=&#34;Yahoo User Interface Version 3&#34;&gt;&lt;abbr title=&#34;Yahoo User Interface Version 3&#34;&gt;&lt;span class=&#34;caps&#34;&gt;YUI3&lt;/span&gt;&lt;/abbr&gt;&lt;/abbr&gt;&lt;/abbr&gt;: Event &amp;#8212; Using Custom Events&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:1&#34; rev=&#34;footnote&#34; title=&#34;Jump back to footnote 1 in the text&#34;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/phiggins42/bloody-jquery-plugins&#34;&gt;Peter Higgins &amp;#8212; pubsub.js&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:2&#34; rev=&#34;footnote&#34; title=&#34;Jump back to footnote 2 in the text&#34;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/mroderick/pubsubjs&#34;&gt;PubSubJS &amp;#8212; dependency free publish/subscribe for javascript&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:3&#34; rev=&#34;footnote&#34; title=&#34;Jump back to footnote 3 in the text&#34;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:4&#34;&gt;
&lt;p&gt;&lt;a href=&#34;http://2010.full-frontal.org/&#34;&gt;Full Frontal Conf 2010&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:4&#34; rev=&#34;footnote&#34; title=&#34;Jump back to footnote 4 in the text&#34;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
        </content>
    </entry>
    <entry>
        <title type="html">The Unscalable Side of Redis</title>
        <author><name>Daniel Knell</name></author>
        <link href="http://artisanofcode.com/archive/2010/06/unscalable-side-redis"/>
        <updated>2010-06-02T00:00:00Z</updated>
        <published>2010-06-02T00:00:00Z</published>
        <id>urn:uuid:20238b12-5a4b-11e1-b379-1093e9024776</id>
        <category scheme="/archive/tags" term="nosql" label="Nosql" />
        <content type="html">
        &lt;p&gt;There is much buzz about redis lately, and most of it with &lt;a href=&#34;/archive/2010/05/little-database-could/&#34; title=&#34;The Little Database That Could&#34;&gt;just cause&lt;/a&gt;,
redis is a blazing fast single threaded data store, that is simple to shard
when dealing with large datasets, and can be easily replicated when reads are
a&amp;nbsp;problem.&lt;/p&gt;
&lt;h2 id=&#34;the-problem&#34;&gt;The&amp;nbsp;Problem&lt;/h2&gt;
&lt;p&gt;Much of the more advanced code I&amp;#8217;ve seen, including some of my own makes good
use of the redis set data-type and the  intersection and union operators to
facilitate&amp;nbsp;filtering.&lt;/p&gt;
&lt;p&gt;Recently I had the chance to experiment with trying to port a huge dataset to
redis, which resulted in a possible edge case where redis would have to
calculate the intersection of three ridiculously large sets (700K items), this
caused a freeze of about four seconds and during that time no other operations
were possible, in a production environment, locking of this nature could cause
catastrophic results  and has pushed back any plans of an all redis&amp;nbsp;backend.&lt;/p&gt;
&lt;p&gt;This is a problem that cant really be solved by the existing scaling mechanisms
redis provides, and it is problem that could affect any code that relies on
automatically adding values to a set, especially many of the auto completion
and search solutions I&amp;#8217;ve seen&amp;nbsp;presented.&lt;/p&gt;
&lt;h2 id=&#34;possible-solutions&#34;&gt;Possible&amp;nbsp;Solutions&lt;/h2&gt;
&lt;p&gt;Recently I was fortunate enough to be able to speak to Rob and Adam from
playnice.ly at the recent &lt;a href=&#34;http://www.meetup.com/Redis-London/&#34;&gt;Redis London&lt;/a&gt;
meetup, and thrash out a few ideas on the&amp;nbsp;problem.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The first solution would be to eliminate the problem sets, or to prevent
  their use in&amp;nbsp;intersections.&lt;/li&gt;
&lt;li&gt;Another option, although not always possible, would be to pre-calculate the
  results on&amp;nbsp;write.&lt;/li&gt;
&lt;li&gt;And finally there is the option of breaking the set into smaller pieces and
  calculating the intersection of each&amp;nbsp;piece.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;what-next&#34;&gt;What&amp;nbsp;Next?&lt;/h2&gt;
&lt;p&gt;The solutions above are a good starting point, but far from fully formed, and
this is an area which deserves far more attention, I&amp;#8217;m hoping that by putting
the word out there, that the redis community can start to move forward towards
concrete solutions and that the code we are producing doesn&amp;#8217;t come back to
haunt us in the&amp;nbsp;future.&lt;/p&gt;
        </content>
    </entry>
    <entry>
        <title type="html">Work Hard, Work Later</title>
        <author><name>Daniel Knell</name></author>
        <link href="http://artisanofcode.com/archive/2010/05/work-hard-work-later"/>
        <updated>2010-05-26T00:00:00Z</updated>
        <published>2010-05-26T00:00:00Z</published>
        <id>urn:uuid:19eab568-5a4b-11e1-ad8f-1093e9024776</id>
        <category scheme="/archive/tags" term="arcitecture" label="Arcitecture" />
        <category scheme="/archive/tags" term="performance" label="Performance" />
        <content type="html">
        &lt;p&gt;In any complex web application there is a need to perform operations on user
request, these operations can become long running, especially when the server
is under load. In order to mitigate this, a web application should leave most
of the work for background&amp;nbsp;processes.&lt;/p&gt;
&lt;h2 id=&#34;benefits&#34;&gt;Benefits&lt;/h2&gt;
&lt;p&gt;Long running actions make the interface feel sluggish, and are subject to
termination by the user, and as mentioned in a &lt;a href=&#34;/archive/2010/05/how-fast-fast-enough/&#34; title=&#34;How Fast is Fast Enough&#34;&gt;previous article&lt;/a&gt;, a slow
website can harm conversion and lead to unhappy&amp;nbsp;users.&lt;/p&gt;
&lt;p&gt;Long running processes can also mount up and when under heavy load, can prevent
the webserver from dealing with new&amp;nbsp;requests.&lt;/p&gt;
&lt;h2 id=&#34;process&#34;&gt;Process&lt;/h2&gt;
&lt;p&gt;When a request is received, the application should do the minimum work required
for it to maintain the user interface, and should instead add any remaining
work to a job/task&amp;nbsp;queue.&lt;/p&gt;
&lt;p&gt;As far as job queues go, you probably cant go wrong with Gearman&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; rel=&#34;footnote&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;, although
there are many others, such as the ruby focused Resque&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; rel=&#34;footnote&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;, as well as the
python focused Celery&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; rel=&#34;footnote&#34;&gt;3&lt;/a&gt;&lt;/sup&gt; and Beanstalk&lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; rel=&#34;footnote&#34;&gt;4&lt;/a&gt;&lt;/sup&gt;, which should be considered to see
which suits you&amp;nbsp;best.&lt;/p&gt;
&lt;p&gt;The exact technology does not matter so much as the process, taking the example
of a blog comment, the backend should validate the form submission and report
ack to the front-end, if the submitted data is valid, a job should be added to
the background job queue to process the comment, performing the database
insert, Askimit or Typekit validation, and sending any notification&amp;nbsp;emails.&lt;/p&gt;
&lt;p&gt;In our comment example, a sudden spike in the rate of comment submissions will
result in a larger queue and a delay in the comments arriving in the moderation
list, rather than causing excess load on the database, and the user gets
immediate feedback without having to wait for the various processes involved
to&amp;nbsp;complete.&lt;/p&gt;
&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;A job queue is a great tool in the quest for responsive web applications,
allowing us to perform complex processing in response to user action actions,
without causing the interface to become unresponsive, and in the mean time
helping to deal with any unforeseeable spikes in&amp;nbsp;traffic.&lt;/p&gt;
&lt;div class=&#34;footnote&#34;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;&lt;a href=&#34;http://gearman.org/&#34;&gt;Gearman&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:1&#34; rev=&#34;footnote&#34; title=&#34;Jump back to footnote 1 in the text&#34;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;&lt;a href=&#34;http://github.com/blog/542-introducing-resque&#34;&gt;Introducing Resque&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:2&#34; rev=&#34;footnote&#34; title=&#34;Jump back to footnote 2 in the text&#34;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;&lt;a href=&#34;http://celeryproject.org/&#34;&gt;Celery - The Distributed Task Queue&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:3&#34; rev=&#34;footnote&#34; title=&#34;Jump back to footnote 3 in the text&#34;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:4&#34;&gt;
&lt;p&gt;&lt;a href=&#34;http://kr.github.com/beanstalkd/&#34;&gt;Beanstalk&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:4&#34; rev=&#34;footnote&#34; title=&#34;Jump back to footnote 4 in the text&#34;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
        </content>
    </entry>
    <entry>
        <title type="html">Grasping the Future, Today</title>
        <author><name>Daniel Knell</name></author>
        <link href="http://artisanofcode.com/archive/2010/05/grasping-future-today"/>
        <updated>2010-05-19T00:00:00Z</updated>
        <published>2010-05-19T00:00:00Z</published>
        <id>urn:uuid:e9f8bfe4-5a4a-11e1-b720-1093e9024776</id>
        <category scheme="/archive/tags" term="javascript" label="Javascript" />
        <category scheme="/archive/tags" term="css" label="Css" />
        <content type="html">
        &lt;p&gt;&lt;abbr title=&#34;Hyper Text Markup Language Version 5&#34;&gt;&lt;span class=&#34;caps&#34;&gt;HTML5&lt;/span&gt;&lt;/abbr&gt; and &lt;abbr title=&#34;Cascading Style Sheets Level 3&#34;&gt;&lt;span class=&#34;caps&#34;&gt;CSS3&lt;/span&gt;&lt;/abbr&gt; have arrived, and the general consensus seems to be that we
should all go out and start using the bountiful wonders it&amp;nbsp;brings.&lt;/p&gt;
&lt;p&gt;Modernizr allows us to make use of these new features by providing a consistent
&lt;abbr title=&#34;Application Programming Interface&#34;&gt;&lt;span class=&#34;caps&#34;&gt;API&lt;/span&gt;&lt;/abbr&gt;,  querying the support for various &lt;abbr title=&#34;Hyper Text Markup Language Version 5&#34;&gt;&lt;span class=&#34;caps&#34;&gt;HTML5&lt;/span&gt;&lt;/abbr&gt; and &lt;abbr title=&#34;Cascading Style Sheets Level 3&#34;&gt;&lt;span class=&#34;caps&#34;&gt;CSS3&lt;/span&gt;&lt;/abbr&gt;, and enabling us to
provide fallback&amp;#8217;s for older user&amp;nbsp;agents.&lt;/p&gt;
&lt;h2 id=&#34;css3&#34;&gt;&lt;abbr title=&#34;Cascading Style Sheets Level 3&#34;&gt;&lt;span class=&#34;caps&#34;&gt;CSS3&lt;/span&gt;&lt;/abbr&gt;&lt;/h2&gt;
&lt;p&gt;By adding classes to the root element, Modernizr allows us to build conditional
branches in css, by prefixing a selector with the feature we wish to&amp;nbsp;detect.&lt;/p&gt;
&lt;div class=&#34;codehilite&#34;&gt;&lt;pre&gt;ul.menu {
    -moz-column-count: 2;
    -moz-column-gap: 20px;
    -webkit-column-count: 2;
    -webkit-column-gap: 20px;
    column-count: 2;
    column-gap: 20px;
}

.no-csscolumns ul.menu li {
    float: left;
    margin-right: 20px;
}

.no-csscolumns ul.menu {
    margin-right: -20px;
    overflow: hidden;
    zoom: 1;
}
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;The new multi column layout features of &lt;abbr title=&#34;Cascading Style Sheets Level 3&#34;&gt;&lt;span class=&#34;caps&#34;&gt;CSS3&lt;/span&gt;&lt;/abbr&gt; allow us to create a
vertically orientated multi column list without the needing to split the list
or change the order of the items within, and Modernizr can help us fall back to
a traditional horizontal floated list in unsupported&amp;nbsp;browsers.&lt;/p&gt;
&lt;h2 id=&#34;html5-apis&#34;&gt;&lt;abbr title=&#34;Hyper Text Markup Language Version 5&#34;&gt;&lt;span class=&#34;caps&#34;&gt;HTML5&lt;/span&gt;&lt;/abbr&gt; &lt;abbr title=&#34;Application Programming Interface&#34;&gt;&lt;span class=&#34;caps&#34;&gt;API&lt;/span&gt;&lt;/abbr&gt;&amp;#8216;s&lt;/h2&gt;
&lt;p&gt;The other side of modernizr is a javascript &lt;abbr title=&#34;Application Programming Interface&#34;&gt;&lt;span class=&#34;caps&#34;&gt;API&lt;/span&gt;&lt;/abbr&gt;, allowing for consistent and
standard approach to feature detection in javascript&amp;nbsp;conditionals.&lt;/p&gt;
&lt;div class=&#34;codehilite&#34;&gt;&lt;pre&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Modernizr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;geolocation&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;nx&#34;&gt;navigator&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;geolocation&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;getCurrentPosition&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;position&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
        &lt;span class=&#34;kd&#34;&gt;var&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;coords&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;position&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;coords&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
        &lt;span class=&#34;nx&#34;&gt;alert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;Location: &amp;#39;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;coords&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;latitude&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;, &amp;#39;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;coords&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;longitude&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;});&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;The GeoLocation &lt;abbr title=&#34;Application Programming Interface&#34;&gt;&lt;span class=&#34;caps&#34;&gt;API&lt;/span&gt;&lt;/abbr&gt; allows a web browser to determine the longitude and
latitude of the device running the browser, but is not widely&amp;nbsp;supported.&lt;/p&gt;
        </content>
    </entry>
    <entry>
        <title type="html">How Fast is Fast Enough?</title>
        <author><name>Daniel Knell</name></author>
        <link href="http://artisanofcode.com/archive/2010/05/how-fast-fast-enough"/>
        <updated>2010-05-10T00:00:00Z</updated>
        <published>2010-05-10T00:00:00Z</published>
        <id>urn:uuid:0c6355ee-5a4b-11e1-8c93-1093e9024776</id>
        <category scheme="/archive/tags" term="arcitecture" label="Arcitecture" />
        <category scheme="/archive/tags" term="performance" label="Performance" />
        <content type="html">
        &lt;p&gt;With the recent changes in googles page rank algorithm; the subject of page
optimization is back on everyones mind, and people are once again looking to
cut precious milliseconds from their loading&amp;nbsp;times.&lt;/p&gt;
&lt;p&gt;There are also many other reasons to optimise your page speed, for-instance,
case studies have shown a correlation between loading time and conversion
rate&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; rel=&#34;footnote&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;, and everyone loves higher conversion&amp;nbsp;rates.&lt;/p&gt;
&lt;p&gt;Instead of the standard approach, where developers delve into the code hunting
or sore spots and optimising until things appear fast, I lean towards a system
of targets, where predefined quotas are assigned to execution time and page
weight, and both designers and developers make achieving them a part of their
standard&amp;nbsp;workflow.&lt;/p&gt;
&lt;h2 id=&#34;why-targets&#34;&gt;Why&amp;nbsp;Targets&lt;/h2&gt;
&lt;p&gt;Targets give us something to work towards, they tell us when we have done enough,
and prevent our expectation from drifting upwards over time, and with the entire
team working towards the same goal, the optimization effort becomes easier to&amp;nbsp;manage.&lt;/p&gt;
&lt;p&gt;The problem is that testing page loading times after every change is time
consuming, but by fixing the values, we can then write unit tests to automate
the process, allowing the work to be shifted to a continuos integration&amp;nbsp;server.&lt;/p&gt;
&lt;p&gt;Clear targets can also be used as part of the decision making process, if a
feature will push the loading time beyond the targets, is the feature likely to
generate more conversion than will be lost due to the longer rendering&amp;nbsp;time?&lt;/p&gt;
&lt;p&gt;And finally there is the impact on mobile broadband users to consider, where
connections are generally slower and bandwidth far more&amp;nbsp;costly.&lt;/p&gt;
&lt;h2 id=&#34;what-targets&#34;&gt;What&amp;nbsp;Targets&lt;/h2&gt;
&lt;p&gt;As one second is the accepted time we can spend doing things before the user
becomes susceptible to distraction&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; rel=&#34;footnote&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;, we should aim to have the page
completely rendered by then, this means page execution time, downloading its
content, any external assets, rendering, and initial javascript&amp;nbsp;execution.&lt;/p&gt;
&lt;p&gt;Ideally, execution time should feel instantaneous to the user, this gives us a
window of 100ms[2] and should be our target for getting things done, with a
maximum of 250 ms if we are to hit our one second overall&amp;nbsp;target.&lt;/p&gt;
&lt;p&gt;When it comes to page weight things start to get a little more complicated,
according to OFCom the average connection in the &lt;span class=&#34;caps&#34;&gt;UK&lt;/span&gt; is around 4Mbps&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; rel=&#34;footnote&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;. Even
if we dedicate half our remaining time, for the user to download everything in
500 ms, we need to aim for a page weight of around &lt;span class=&#34;caps&#34;&gt;200KB&lt;/span&gt;, and should generally
strive for about half&amp;nbsp;that.&lt;/p&gt;
&lt;p&gt;In total we have now used up to 75% of our one second target, this gives us
another 250 ms for the browser to execute javascript, and finish rendering the&amp;nbsp;page.&lt;/p&gt;
&lt;h2 id=&#34;conclusions&#34;&gt;Conclusions&lt;/h2&gt;
&lt;p&gt;So to summarize, by adopting a targets orientated approach, we should be able
to keep on top of our page execution times and weight, providing a faster and
more fluid user experience, resulting in happier users, higher conversion,
reduced bandwidth bills, and partially future proof our sites towards the
growing number of 3G&amp;nbsp;connections.&lt;/p&gt;
&lt;h2 id=&#34;summary&#34;&gt;Summary&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Criteria&lt;/th&gt;
&lt;th&gt;Target&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Execution Time&lt;/td&gt;
&lt;td&gt;100 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Page Weight&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;caps&#34;&gt;100KB&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Maximum Execution Time&lt;/td&gt;
&lt;td&gt;250 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Maximum Page Weight&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;caps&#34;&gt;200KB&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class=&#34;footnote&#34;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;&lt;a href=&#34;http://en.oreilly.com/velocity2009/public/schedule/detail/7709&#34;&gt;Shopzilla&amp;#8217;s Site Redo - You Get What You Measure&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:1&#34; rev=&#34;footnote&#34; title=&#34;Jump back to footnote 1 in the text&#34;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;&lt;a href=&#34;http://www.useit.com/papers/responsetime.html&#34;&gt;Response Times: The Three Important Limits&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:2&#34; rev=&#34;footnote&#34; title=&#34;Jump back to footnote 2 in the text&#34;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;&lt;a href=&#34;http://www.ofcom.org.uk/research/telecoms/reports/broadband_speeds/broadband_speeds/broadbandspeeds.pdf&#34;&gt;&lt;span class=&#34;caps&#34;&gt;UK&lt;/span&gt; broadband speeds 2009&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:3&#34; rev=&#34;footnote&#34; title=&#34;Jump back to footnote 3 in the text&#34;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
        </content>
    </entry>
    <entry>
        <title type="html">The Little Database that Could</title>
        <author><name>Daniel Knell</name></author>
        <link href="http://artisanofcode.com/archive/2010/05/little-database-could"/>
        <updated>2010-05-05T00:00:00Z</updated>
        <published>2010-05-05T00:00:00Z</published>
        <id>urn:uuid:11b47f50-5a4b-11e1-9222-1093e9024776</id>
        <category scheme="/archive/tags" term="nosql" label="Nosql" />
        <content type="html">
        &lt;p&gt;When redis first crossed my radar last year, I had some serious doubts about the
numbers people were quoting, doubts my own testing&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; rel=&#34;footnote&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; inevitably prove to be
completely&amp;nbsp;unfounded.&lt;/p&gt;
&lt;p&gt;Performance, though impressive,  is but a small part of what makes this little
database so amazing. Despite being clasified as a key-value store, what really
sets redis apart is its rich set of datatypes, including not only strings, but
lists, sets, and hashes as&amp;nbsp;well.&lt;/p&gt;
&lt;h2 id=&#34;try-redis&#34;&gt;Try&amp;nbsp;Redis&lt;/h2&gt;
&lt;p&gt;Installing redis is ridiculous simple, and you can get it up and running in a
matter of seconds. In a new terminal&amp;nbsp;try:&lt;/p&gt;
&lt;div class=&#34;codehilite&#34;&gt;&lt;pre&gt;&lt;span class=&#34;nv&#34;&gt;$ &lt;/span&gt;wget http://redis.googlecode.com/files/redis-1.2.6.tar.gz
&lt;span class=&#34;nv&#34;&gt;$ &lt;/span&gt;tar -xzf redis-1.2.6.tar.gz
&lt;span class=&#34;nv&#34;&gt;$ &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;cd &lt;/span&gt;redis-1.2.6
&lt;span class=&#34;nv&#34;&gt;$ &lt;/span&gt;make
&lt;span class=&#34;nv&#34;&gt;$ &lt;/span&gt;./redis-server
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;One of the simplest ways of interacting with redis is via the interactive
console, in a new  terminal you can launch the cli client with the following&amp;nbsp;command:&lt;/p&gt;
&lt;div class=&#34;codehilite&#34;&gt;&lt;pre&gt;&lt;span class=&#34;nv&#34;&gt;$ &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;cd &lt;/span&gt;redis-1.2.6
&lt;span class=&#34;nv&#34;&gt;$ &lt;/span&gt;./redis-cli
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;And you can now interact with redis via its rich yet simple set of
&lt;a href=&#34;http://code.google.com/p/redis/wiki/CommandReference&#34; title=&#34;Redis Command Reference&#34;&gt;commands&lt;/a&gt;&lt;/p&gt;
&lt;div class=&#34;codehilite&#34;&gt;&lt;pre&gt;redis&amp;gt; KEYS *

redis&amp;gt; SET foo bar
OK
redis&amp;gt; KEYS *
foo
redis&amp;gt; GET foo
bar
redis&amp;gt; SADD breakfast bacon
(integer) 1
redis&amp;gt; SADD breakfast eggs
(integer) 1
redis&amp;gt; SADD breakfast fruit
(integer) 1
redis&amp;gt; SMEMBERS breakfast
1. bacon
2. fruit
3. eggs
redis&amp;gt; SREM breakfast fruit
(integer) 1
redis&amp;gt; SMEMBERS breakfast
1. bacon
2. eggs
redis&amp;gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;h2 id=&#34;usage&#34;&gt;Usage&lt;/h2&gt;
&lt;p&gt;March brought with it my first opportunity to deploy redis into my works
production environment, and I have since been de-normalizing much of the sore
spots in our existing relational database into a cluster of redis&amp;nbsp;servers.&lt;/p&gt;
&lt;p&gt;So far redis has proven its self to be an ideal storage solution&amp;nbsp;for:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;High request volume environments such as comet based message&amp;nbsp;queues.&lt;/li&gt;
&lt;li&gt;A denormalized push&amp;nbsp;cache.&lt;/li&gt;
&lt;li&gt;&lt;span class=&#34;caps&#34;&gt;URL&lt;/span&gt; routing&amp;nbsp;information.&lt;/li&gt;
&lt;li&gt;An intermediate store for analyical&amp;nbsp;data.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Using redis has not only resulted performance gains, but in places its
simplistic model has also lead to more readable&amp;nbsp;code.&lt;/p&gt;
&lt;div class=&#34;footnote&#34;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;130,000 reads and 80,000 writes per second on my machine&amp;#160;&lt;a href=&#34;#fnref:1&#34; rev=&#34;footnote&#34; title=&#34;Jump back to footnote 1 in the text&#34;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
        </content>
    </entry>
    <entry>
        <title type="html">Hello World</title>
        <author><name>Daniel Knell</name></author>
        <link href="http://artisanofcode.com/archive/2010/05/hello-world"/>
        <updated>2010-05-01T00:00:00Z</updated>
        <published>2010-05-01T00:00:00Z</published>
        <id>urn:uuid:f0eee74c-5a4a-11e1-91a4-1093e9024776</id>
        <content type="html">
        &lt;p&gt;After some long term procrastinating over what to do with my
&lt;a href=&#34;/about/&#34;&gt;personal website&lt;/a&gt;, I have finally hammered out some code and a design
I&amp;#8217;m satisfied&amp;nbsp;with.&lt;/p&gt;
&lt;p&gt;Now i find myself with the proverbial blank slate and a no idea where to be
begin, but I will endeavour to fill the pages with nuggets of mac, linux, and
web development&amp;nbsp;goodness.&lt;/p&gt;
        </content>
    </entry>
</feed>
