<?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>puremango.co.uk</title>
	<atom:link href="http://www.puremango.co.uk/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.puremango.co.uk</link>
	<description>innovative coding, tutorials, web stuff. celebrating 5 years online.</description>
	<lastBuildDate>Thu, 02 Sep 2010 09:04:28 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Some tweetable #js1k demos</title>
		<link>http://www.puremango.co.uk/2010/08/some-tweetable-js1k-demos/</link>
		<comments>http://www.puremango.co.uk/2010/08/some-tweetable-js1k-demos/#comments</comments>
		<pubDate>Wed, 01 Sep 2010 07:31:24 +0000</pubDate>
		<dc:creator>Howard Yeend</dc:creator>
				<category><![CDATA[javascript]]></category>
		<category><![CDATA[canvas]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[demo]]></category>
		<category><![CDATA[images]]></category>
		<category><![CDATA[js1k]]></category>

		<guid isPermaLink="false">http://www.puremango.co.uk/?p=1222</guid>
		<description><![CDATA[JS1k is consuming me at the moment. I saw this entry by strager and it inspired me to push for a tweetable (&#60;=140 byte) demo based on his. By dropping the save/restore and alpha blending features, I was able to come up with a few candidates which I think look fairly pretty. Unlike my previous [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignright" title="strager's entry" src="http://www.puremango.co.uk/js1k/strager.png" alt="" width="140" height="140" /><a href="http://js1k.com/home" target="_blank">JS1k</a> is consuming me at the moment. I saw <a href="http://js1k.com/demo/592" target="_blank">this entry</a> by <a href="http://strager.net/blag/" target="_blank">strager</a> and it inspired me to push for a tweetable (&lt;=140 byte) demo based on his.</p>
<p>By dropping the save/restore and alpha blending features, I was able to come up with a few candidates which I think look fairly pretty.</p>
<p>Unlike my previous <a href="http://js1k.com/demo/574" target="_blank">allRGB </a>and <a href="http://js1k.com/demo/595" target="_blank">rot13</a> entries, where I had a definite goal in mind, here I&#8217;m really just playing with parameters until something cool appears on the screen. Which is kinda neat, it recaptures that innocent experimental spirit which was what first attracted me to programming when I was a kid.</p>
<p><span id="more-1222"></span></p>
<p><a href="http://www.puremango.co.uk/js1k/stainedglass.html" target="_blank"><img class="alignleft" title="Rose window" src="http://www.puremango.co.uk/js1k/rose.png" alt="" width="140" height="140" /></a></p>
<p><strong><a href="http://www.puremango.co.uk/js1k/stainedglass.html" target="_blank">Stained Glass (140b)</a>.</strong> A stained glass window, ever expanding and becoming more intricate. There&#8217;s a nice &#8216;grayscale&#8217; effect due to anti-aliasing and the fact that we&#8217;re drawing over some lines at slight offsets, making them thicker and so appearing darker. I started off using &#8216;with&#8217; in the code like @strager, but actually found I saved bytes without it, because setInterval code is executed in the global scope but we need to do the translate outside setInterval- it&#8217;s more succinct to just say &#8216;d.&#8217; everywhere.</p>
<p><code>h=60,d=document.body.children[0];d.height*=h;d=d.getContext('2d');d.translate(h,h),setInterval("d.strokeRect(9,9,h/2,h++/2),d.rotate(90)",9)</code></p>
<p><strong><a href="http://js1k.com/demo/606" target="_blank">Exploding Web (139b)</a>.</strong> <a href="http://js1k.com/demo/606" target="_blank"><img class="alignright" title="Web" src="http://www.puremango.co.uk/js1k/web.png" alt="" width="140" height="140" /></a>This one starts as a spirograph then quickly destablises into a sunburst. But as soon as you think you know the pattern, a new one emerges &#8211; after running for a few seconds, you can suddenly see hints of beams of light seen through a forest. Or is it just a mess of lines? ;)</p>
<p><code>h=99,d=document.body.children[0];d.height*=h;d=d.getContext('2d');d.translate(h,h);setInterval("d.strokeRect(9,9,h/2+--h,h);d.rotate(h)",1)</code></p>
<p><a href="http://js1k.com/demo/600" target="_blank"><img class="alignleft" title="Moon" src="http://www.puremango.co.uk/js1k/moon.png" alt="" width="140" height="140" /></a><strong><a href="http://js1k.com/demo/600" target="_blank">Moonrise (140b)</a>.</strong> The interesting thing about all these demos is the way they evolve the longer they&#8217;re run. To me, this one really has depth. First it&#8217;s a new dawn with the sun shining, then the moon takes over and its light reflects over the waters of a rippling lake. As you scroll down the page, the lake transforms into an abstract network of shapes which have an inscrutible pattern.</p>
<p><code>h=99,d=document.body.children[0];d.height*=h;d=d.getContext('2d');d.translate(h,h),setInterval("d.strokeRect(10,9,h/3,h++/3),d.rotate(9)",2)</code></p>
<p><a href="http://js1k.com/demo/595" target="_blank"><img class="alignright" title="rot13" src="http://www.puremango.co.uk/js1k/rot13.png" alt="" width="140" height="140" /></a><strong><a href="http://js1k.com/demo/595" target="_blank">rot13 (138b)</a></strong>. An entry which actually does something useful in under 140 bytes! Performs the rot13 substitution cipher on user input. Loops until you press cancel, at which point it quits with an error. Don&#8217;t think I can fix that in the 2 remaining bytes :( I&#8217;ve also written a &#8216;full&#8217; version in 1000ish bytes, which I&#8217;ll tidy and submit later. Slap &#8220;javascript:&#8221; on the front and you&#8217;ve got a very handy <a href="javascript:for(r=o='rot13';o=prompt(r,o).replace(/[a-z]/gi,function(c){return String.fromCharCode((n=c.charCodeAt()+13)&gt;122||n&lt;104&amp;&amp;n&gt;90?n-26:n)}););">bookmarklet</a> :)</p>
<p><code>for(r=o='rot13';o=prompt(r,o).replace(/[a-z]/gi,function(c){return String.fromCharCode((n=c.charCodeAt()+13)&gt;122||n&lt;104&amp;&amp;n&gt;90?n-26:n)}););</code></p>
<p><a href="http://js1k.com/demo/578" target="_blank"><img class="alignleft" title="Blocks" src="http://www.puremango.co.uk/js1k/blocks.png" alt="" width="140" height="140" /></a><strong><a href="http://js1k.com/demo/578" target="_blank">Blocks of colour (140b)</a>.</strong> This one I&#8217;d entered a few days ago as my first twitter sized entry. It&#8217;s 140 bytes including the #js1k hashtag, which is pretty funky. It&#8217;s similar to <a href="http://chrisfrancis27.tumblr.com/" target="_blank">chrisfrancis27</a>&#8216;s &#8216;fence&#8217; entry, and uses the colour randomising code from his entry. The &#8220;|0&#8243; part performs type conversion, and seems to be required for Chrome.</p>
<p><code>r=Math.random;setInterval('with(document.body.children[0].getContext("2d"))fillStyle="#"+(1E6*r()|0),fillRect(r()*290,r()*99,9,9)',2)//#js1k</code></p>
<p><a href="http://www.puremango.co.uk/js1k/cave.html" target="_blank"><img class="alignright" title="Cave of Evil" src="http://www.puremango.co.uk/js1k/cave.png" alt="" width="140" height="140" /></a></p>
<p><a href="http://www.puremango.co.uk/js1k/cave.html" target="_blank"><strong>Cave of Evil (136b)</strong></a>. Showing off <em>three</em> new features here, firstly a new way to access the canvas &#8211; most people so far are using document.body.children[0], but document.body.children.c is one byte shorter, which helps. Also, this demo sets the width and the height in one move: height=width*=h=9, which is pretty cool, and finally I&#8217;m using canvas&#8217;s globalAlpha property to create a really nice greyscale effect. Damn, this is addictive!<br />
<code>with(document.body.children.c)height=width*=h=9,c=getContext('2d'), c.globalAlpha=.008,setInterval("c.fillRect(0,0,h,h),c.rotate(h++)",1)</code></p>
<p>Update: Chrome doesn&#8217;t like globalAlpha&#8217;s <0.01, and Opera doesn't like <0.1, so I've updated the code.</p>
<p><code>with(document.body.children.c)height=width*=h=9,c=getContext(&#8217;2d&#8217;), c.globalAlpha=.1,setInterval(&#8220;c.fillRect(0,0,h,h),c.rotate(h++)&#8221;,5)</code></p>
<p>It's almost as pretty :)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.puremango.co.uk/2010/08/some-tweetable-js1k-demos/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>js1k: an allRGB entry in </title>
		<link>http://www.puremango.co.uk/2010/08/js1k-allrgb-entry/</link>
		<comments>http://www.puremango.co.uk/2010/08/js1k-allrgb-entry/#comments</comments>
		<pubDate>Mon, 30 Aug 2010 11:57:09 +0000</pubDate>
		<dc:creator>Howard Yeend</dc:creator>
				<category><![CDATA[javascript]]></category>
		<category><![CDATA[allrgb]]></category>
		<category><![CDATA[demo]]></category>
		<category><![CDATA[geek]]></category>
		<category><![CDATA[images]]></category>
		<category><![CDATA[js1k]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://www.puremango.co.uk/?p=1173</guid>
		<description><![CDATA[It&#8217;s contest season! The An Event Apart 10k JavaScript app contest has just ended (my entry got 2½/5), there&#8217;s a node.js contest, and the JS1k contest is ending on Sept 10th. JS1k is a much purer contest, disallowing any external libraries, while the 10k contest allowed things like jQuery and external web services. As Frederick [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://js1k.com/demo/574" target="_blank"><img class="alignleft size-full wp-image-1190" title="AllRGB" src="http://www.puremango.co.uk/images/allrgb.png" alt="" width="208" height="208" /></a>It&#8217;s contest season! The An Event Apart 10k JavaScript app contest has just ended (<a href="http://10k.aneventapart.com/entry/243" target="_blank">my entry</a> got 2½/5), there&#8217;s a <a href="http://nodeknockout.com/" target="_blank">node.js contest</a>, and the JS1k contest is ending on Sept 10th. JS1k is a much purer contest, disallowing any external libraries, while the 10k contest allowed things like jQuery and external web services. As <a href="http://sustainablecode.tumblr.com/post/1027976375/1k-of-pure-javascript-addiction" target="_blank">Frederick Polgardy</a> puts it, js1k is &#8220;An exercise in constraint, resulting in a kind of executable haiku&#8221;.</p>
<p>For js1k, <a href="http://js1k.com/demo/574" target="_blank">I&#8217;ve entered</a> a port of my <a href="http://www.puremango.co.uk/2010/02/allrgb-entry-php-image-manipulation/" target="_self">PHP allRGB entry</a>. The <a href="http://www.allrgb.com" target="_blank">allRGB project</a> is a great idea in itself &#8211; create an image which contains every possible colour in the RGB space exactly once. That&#8217;s 256*256*256 colours (=16777216), in a 4096&#215;4096 image. Quite a challenge for PHP, and certainly not the kind of thing you&#8217;d attempt in JavaScript, right? ;D<br />
<span id="more-1173"></span><br />
The code itself is pretty simple stuff &#8211; three nested for loops and you&#8217;re basically done. A few little tweaks to make sure it runs fairly smoothly in all browsers. Unlike the PHP version you can&#8217;t really just set and forget, so I&#8217;m using setTimeout to break the task down into smaller chunks, which means the browser won&#8217;t trigger its &#8220;This script is running slowly&#8221; message. I also use window.scroll to show the user that something&#8217;s actually happening on screen.</p>
<p>As I mentioned, this isn&#8217;t the kind of thing you&#8217;d normally turn to JavaScript for, and it puts quite a strain on the browser. It&#8217;s very interesting to see how the different browsers fare. Opera is the fastest, followed closely by Chome, then Firefox. Safari puts on a generally poor show, being slow and having some rendering problems while the drawing/scrolling is happening, but it does work in the end. It doesn&#8217;t run in IE 8 or 9, I&#8217;ll probably have a look at that at some point, it&#8217;s bound to be be something silly.</p>
<p>The final <a href="http://fmarcia.info/jsmin/test.html" target="_blank">minified</a> code comes in at 713 bytes. I could get that down further for sure, but there&#8217;s no need to just yet.</p>
<p><a href="http://js1k.com/demo/574" target="_blank">Check out the demo here.</a></p>
<p>Here&#8217;s the original source. Leave a comment if you can spot the IE errors :)</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// declare shorthand vars</span>
<span style="color: #003366; font-weight: bold;">var</span> o<span style="color: #339933;">=</span>document.<span style="color: #660066;">body</span><span style="color: #339933;">,</span>c<span style="color: #339933;">=</span>o.<span style="color: #660066;">children</span><span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>w<span style="color: #339933;">=</span><span style="color: #CC0000;">4096</span><span style="color: #339933;">,</span>n<span style="color: #339933;">=</span><span style="color: #CC0000;">256</span><span style="color: #339933;">,</span>t<span style="color: #339933;">=</span>c.<span style="color: #660066;">getContext</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;2d&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>s<span style="color: #339933;">=</span>x<span style="color: #339933;">=</span>y<span style="color: #339933;">=</span><span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// set canvas dimensions and background</span>
c.<span style="color: #660066;">width</span><span style="color: #339933;">=</span>c.<span style="color: #660066;">height</span><span style="color: #339933;">=</span>w<span style="color: #339933;">;</span>c.<span style="color: #660066;">style</span>.<span style="color: #660066;">background</span><span style="color: #339933;">=</span><span style="color: #3366CC;">'#DDD'</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// add a pretty description</span>
h<span style="color: #339933;">=</span>document.<span style="color: #660066;">createElement</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'p'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
h.<span style="color: #660066;">innerHTML</span><span style="color: #339933;">=</span><span style="color: #3366CC;">'&lt;p style=&quot;font-family:verdana;font-size:10pt;&quot;&gt;All&lt;b style=&quot;color:red;&quot;&gt;R&lt;/b&gt;&lt;b style=&quot;color:#0F0;&quot;&gt;G&lt;/b&gt;&lt;b style=&quot;color:blue;&quot;&gt;B&lt;/b&gt; entry in JS, in 719b. Rendering every RGB colour exactly once '</span><span style="color: #339933;">+</span>w<span style="color: #339933;">+</span><span style="color: #3366CC;">'x'</span><span style="color: #339933;">+</span>w<span style="color: #339933;">+</span><span style="color: #3366CC;">'px - '</span><span style="color: #339933;">+</span><span style="color: #009900;">&#40;</span>w<span style="color: #339933;">*</span>w<span style="color: #009900;">&#41;</span><span style="color: #339933;">+</span><span style="color: #3366CC;">' cols.&lt;/p&gt;'</span><span style="color: #339933;">;</span>
o.<span style="color: #660066;">insertBefore</span><span style="color: #009900;">&#40;</span>h<span style="color: #339933;">,</span>o.<span style="color: #660066;">firstChild</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// draw function:</span>
<span style="color: #003366; font-weight: bold;">function</span> d<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;">// draw the next few reds</span>
  e<span style="color: #339933;">=</span>s<span style="color: #339933;">+</span><span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>
  <span style="color: #006600; font-style: italic;">// draw full blue and green for each red</span>
  <span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span>r<span style="color: #339933;">=</span>s<span style="color: #339933;">;</span>r<span style="color: #339933;">++&lt;</span>e<span style="color: #339933;">;</span><span style="color: #009900;">&#41;</span><span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span>g<span style="color: #339933;">=</span><span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>g<span style="color: #339933;">++&lt;</span>n<span style="color: #339933;">;</span><span style="color: #009900;">&#41;</span><span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span>b<span style="color: #339933;">=</span><span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>b<span style="color: #339933;">++&lt;</span>n<span style="color: #339933;">;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    <span style="color: #006600; font-style: italic;">// set the colour</span>
    t.<span style="color: #660066;">fillStyle</span><span style="color: #339933;">=</span><span style="color: #3366CC;">&quot;rgb(&quot;</span><span style="color: #339933;">+</span>r<span style="color: #339933;">+</span><span style="color: #3366CC;">&quot;,&quot;</span><span style="color: #339933;">+</span>g<span style="color: #339933;">+</span><span style="color: #3366CC;">&quot;,&quot;</span><span style="color: #339933;">+</span>b<span style="color: #339933;">+</span><span style="color: #3366CC;">&quot;)&quot;</span><span style="color: #339933;">;</span>
    <span style="color: #006600; font-style: italic;">// draw a pixel</span>
    t.<span style="color: #660066;">fillRect</span><span style="color: #009900;">&#40;</span>x<span style="color: #339933;">,</span>y<span style="color: #339933;">,</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #006600; font-style: italic;">// increment x and y if needed, and scroll the page so the user can see what's going on.</span>
    <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">++</span>x<span style="color: #339933;">&gt;=</span>w<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>x<span style="color: #339933;">=</span><span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>y<span style="color: #339933;">++;</span>if<span style="color: #009900;">&#40;</span>y<span style="color: #339933;">&gt;</span><span style="color: #CC0000;">300</span> <span style="color: #339933;">&amp;&amp;</span> y<span style="color: #339933;">%</span>5<span style="color: #339933;">==</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><span style="color: #000066;">scroll</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span>y<span style="color: #339933;">-</span><span style="color: #CC0000;">300</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #006600; font-style: italic;">// chunk the drawing so it doesn't cause a &quot;this script is running slowly&quot; message</span>
  <span style="color: #006600; font-style: italic;">// this also prevents the browser from becoming completely non-responsive. You can still close the tab while it's running</span>
  <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>e<span style="color: #339933;">&lt;=</span>n<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>s<span style="color: #339933;">=</span>e<span style="color: #339933;">;</span>setTimeout<span style="color: #009900;">&#40;</span>d<span style="color: #339933;">,</span><span style="color: #CC0000;">1</span><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: #000066;">alert</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'done'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// warn user</span>
<span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000066;">confirm</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'This will hang Safari til done. Run?'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> d<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://www.puremango.co.uk/2010/08/js1k-allrgb-entry/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Writing a JavaScript app in 10k (#aea10k) – Part One</title>
		<link>http://www.puremango.co.uk/2010/08/writing-a-javascript-app-in-10k-aea10k-part-one/</link>
		<comments>http://www.puremango.co.uk/2010/08/writing-a-javascript-app-in-10k-aea10k-part-one/#comments</comments>
		<pubDate>Sat, 28 Aug 2010 16:13:43 +0000</pubDate>
		<dc:creator>Howard Yeend</dc:creator>
				<category><![CDATA[javascript]]></category>
		<category><![CDATA[web]]></category>
		<category><![CDATA[aea10k]]></category>
		<category><![CDATA[contest]]></category>
		<category><![CDATA[demo]]></category>
		<category><![CDATA[tools]]></category>

		<guid isPermaLink="false">http://www.puremango.co.uk/?p=1163</guid>
		<description><![CDATA[Two weeks ago I discovered the 10k JavaScript contest organised by An Event Apart. It challenged developers to &#8220;inspire the web with just 10K&#8221;. I knew I&#8217;d be cutting things fine with just 11 days left before the deadline (including 5 at work and 3 on holiday!) but I was desperate to enter an application. [...]]]></description>
			<content:encoded><![CDATA[<p>Two weeks ago I discovered the 10k JavaScript contest organised by An  Event Apart. It challenged developers to &#8220;inspire the web with just  10K&#8221;. I knew I&#8217;d be cutting things fine with just 11 days left before  the deadline (including 5 at work and 3 on holiday!) but I was desperate  to enter an application.</p>
<p>You can play with the final entry right here &#8211; <a href="http://10k.aneventapart.com/entry/details/243" target="_blank">http://10k.aneventapart.com/entry/details/243</a> &#8211; voting closes <em><strong>today</strong></em> so please be generous with your votes and comments. I&#8217;ve literally just  now come back from holiday so I haven&#8217;t had a chance to badger everyone  to vote yet. Go and vote! ;)</p>
<p>The idea&#8217;s been kicking around my head for a while: <span id="more-1163"></span>A  desktop/bookmarking app with a google maps style interface. The general  concept was that current approaches to bookmark management, navigation  and retrieval focus on either tagging with keywords or hierarchical  organisation into categories, but the idea of a &#8220;desktop&#8221; is a visual metaphor, and we  tend to remember things better in visual and spatial terms. Also, with  touch interfaces on the rise, reducing the keyboard&#8217;s role looked like a  worthy goal.</p>
<p>So, &#8216;SkyTop&#8217; is a mouse-navgiated landscape of icons which can be dragged, panned and zoomed. You can arrange clusters of similarly themed icons by dragging them closer together. In this  way you can have all your work icons in one place, and when you&#8217;re done, zoom and pan across to your hobby icons. No need to type any tags or search through pages of bookmarks &#8211; just zoom right out and you&#8217;ll see where all your icons are. You&#8217;ll remember that you put google.com up to the right near the other search engines. I think it&#8217;s a powerful concept. I&#8217;m not sure I&#8217;ve pulled it off quite as perfectly as I&#8217;d have liked, but the basic interface is there and working in all major browsers, and for 10k I&#8217;m pretty happy.</p>
<p>In a future post I&#8217;ll do a technical write-up (lots of good stuff  to talk about there!) and release the un-minified code, but for the moment just take a look over the app  and let me know your thoughts on it. I think there&#8217;s definite room for  improvement in the icon display, and I think having a background image  which zooms and pans with the icons might help the user to understand the interface better. I&#8217;d love to hear what you think of the concept, and my implementation of it :0)</p>
<p>PS: <a href="http://10k.aneventapart.com/entry/details/243" target="_blank">Vote right now</a>, then <a href="http://twitter.com/puremango" target="_blank">follow me on twitter</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.puremango.co.uk/2010/08/writing-a-javascript-app-in-10k-aea10k-part-one/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Some thoughts on JavaScript</title>
		<link>http://www.puremango.co.uk/2010/07/thoughts-on-javascript/</link>
		<comments>http://www.puremango.co.uk/2010/07/thoughts-on-javascript/#comments</comments>
		<pubDate>Wed, 14 Jul 2010 09:01:30 +0000</pubDate>
		<dc:creator>Howard Yeend</dc:creator>
				<category><![CDATA[Firefox]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[memory]]></category>
		<category><![CDATA[sessions]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://www.puremango.co.uk/?p=869</guid>
		<description><![CDATA[I don&#8217;t know about you, but I grew up doing image rollovers in JS and other groundbreaking &#8220;dhtml&#8221; stuff. Since then CSS has evolved, web standards and browsers have evolved, and things are much much nicer than before. One thing that is starting to change is the way we fundamentally approach javascript. Not simply the [...]]]></description>
			<content:encoded><![CDATA[<p>I don&#8217;t know about you, but I grew up doing image rollovers in JS and other groundbreaking &#8220;dhtml&#8221; stuff. Since then CSS has evolved, web standards and browsers have evolved, and things are much much nicer than before.</p>
<p>One thing that is starting to change is the way we fundamentally approach javascript. Not simply the recent popularity of libraries such as jQuery, allowing us to literally &#8220;change the way we write javascript&#8221;, but also there&#8217;s now much more awareness of the power that javascript has, and we&#8217;re doing more mission-critical stuff with JS. We&#8217;re moving from favouring simple procedural snippets of javascript that add twinkles to the page to fully object oriented JS applications, exporting great swathes of functionality away from the servers and onto the client.</p>
<p>This is a great thing. In fact it&#8217;s little short of a miracle; the servers are running faster <em>and so are the clients</em>! There seems to be no trade-off; by deeply integrating JavaScript into our web applications we&#8217;ve gained speed at both ends!</p>
<p><strong>Not quite though.</strong></p>
<p><span id="more-869"></span></p>
<p>JavaScript uses garbage collection to keep the memory usage down &#8211; if a variable is never referenced again in the code, it can safely be deleted from memory, freeing the resources associated with it. But there are various techniques to automatic memory management, and there are some pitfalls. For example, a common way to determine whether a variable is safe to delete is to count the references to that variable in the forward path of the code; when there are no more references, it can be deleted. But when two variables reference each other, that can create a circular reference from which there is no escape.</p>
<p>An article on Mozilla&#8217;s developer site explains <a href="https://developer.mozilla.org/en/A_re-introduction_to_JavaScript#Memory_leaks" target="_blank" rel="external">how memory leaks are created</a>, and how to avoid them. The trick is understanding when a specific type of circular reference is created. From the article:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">function</span> leakMemory<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> el <span style="color: #339933;">=</span> document.<span style="color: #660066;">getElementById</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'el'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #003366; font-weight: bold;">var</span> o <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span> <span style="color: #3366CC;">'el'</span><span style="color: #339933;">:</span> el <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
    el.<span style="color: #660066;">o</span> <span style="color: #339933;">=</span> o<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<blockquote><p>The circular reference formed above creates a memory leak; IE will not free the memory used by<em> el</em> and <em>o</em> until the browser is completely restarted.</p></blockquote>
<p>Yes, you read that right, <strong>completely restarted</strong>. Not just when the tab is closed, that memory will stay locked until you restart IE. This is so crazy I&#8217;m actually a little dubious as to whether it&#8217;s still true.</p>
<p>Ok you may be thinking, but surely this doesn&#8217;t happen that often in practice? Consider this example:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">function</span> addHandler<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> el <span style="color: #339933;">=</span> document.<span style="color: #660066;">getElementById</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'el'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    el.<span style="color: #660066;">onclick</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: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">style</span>.<span style="color: #660066;">backgroundColor</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'red'</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>The article goes into some detail about how these examples leak, and how to spot and fix them, and I highly recommend reading the entire page, not just the memory leaks section.</p>
<p>I&#8217;m currently in the middle of &#8220;Javascript: The Good Parts&#8221; by Douglas Crockford and highly recommend it, it&#8217;s pretty thin at 100 pages not including the appendices, but it is of exceptionally high quality &#8211; you&#8217;ll start understanding and writing better javascript from day one. Crockford also has a great page on <a href="http://javascript.crockford.com/memory/leak.html" target="_blank" rel="external">memory leaks in JavaScript</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.puremango.co.uk/2010/07/thoughts-on-javascript/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Fast PHP array_unique for removing duplicates</title>
		<link>http://www.puremango.co.uk/2010/06/fast-php-array_unique-for-removing-duplicates/</link>
		<comments>http://www.puremango.co.uk/2010/06/fast-php-array_unique-for-removing-duplicates/#comments</comments>
		<pubDate>Mon, 21 Jun 2010 08:23:21 +0000</pubDate>
		<dc:creator>Howard Yeend</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[array_flip]]></category>
		<category><![CDATA[array_reverse]]></category>
		<category><![CDATA[array_unique]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[developer]]></category>
		<category><![CDATA[fast]]></category>
		<category><![CDATA[optimisation]]></category>
		<category><![CDATA[tech]]></category>

		<guid isPermaLink="false">http://www.puremango.co.uk/?p=1039</guid>
		<description><![CDATA[PHP&#8217;s native dedupe function, array_unique, can be slow for large amount of input. Here I&#8217;m going to talk about a simple function that performs the same task but which runs a lot faster. Often, people spout PHP optimisation advice that is incredibly misguided, so I want to make it clear up-front that you should be [...]]]></description>
			<content:encoded><![CDATA[<p>PHP&#8217;s native dedupe function, <a href="http://php.net/manual/en/function.array-unique.php" target="_blank">array_unique</a>, can be slow for large amount of input. Here I&#8217;m going to talk about a simple function that performs the same task but which runs a lot faster.</p>
<p>Often, people spout PHP optimisation advice that is incredibly misguided, so I want to make it clear up-front that you should be benchmarking your scripts using xdebug before you start optimising, and very often the real bottlenecks cannot be avoided by using &#8220;micro-optimization&#8221;. Here&#8217;s a nice PDF on <a href="http://ilia.ws/files/Dutch_PHP_Conference_2010_OPM.pdf" target="_blank">Common Optimization Mistakes</a>.</p>
<p>Now I&#8217;ve got that disclaimer out of the way, I believe it&#8217;s OK to talk about making a faster array_unique because it&#8217;s often used on large amounts of data &#8211; for example removing duplicate email addresses, and as such there are genuine use cases for a fast array_unique in PHP. Also our fast_unique function can be several seconds faster than array_unique so we&#8217;re not necessarily talking about micro-optimisation here; on 200k duplicate entries, array_unique takes nearly 5 seconds on my windows dev box, fast_unique takes &lt;1 second on the same data. On 2 million entires the results are staggering &#8211; performance graphs are given below (but then, why are you doing that kind of work in PHP?).</p>
<p>The function looks like this:<br />
<span id="more-1039"></span></p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> fast_unique<span style="color: #009900;">&#40;</span><span style="color: #000088;">$input</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #666666; font-style: italic;">// Code documented at: http://www.puremango.co.uk/?p=1039</span>
	<span style="color: #b1b100;">return</span> <span style="color: #990000;">array_flip</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">array_flip</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">array_reverse</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$input</span><span style="color: #339933;">,</span><span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>This will return a copy of the input array with duplicates removed and keys preserved.</p>
<p>When using this function, there are some important caveats you should be aware of:</p>
<ol>
<li>The data is not returned in the same order as array_unique would return it. You can add a ksort afterwards, but this will reduce the speed savings. Key order preservation is often not required, so I haven&#8217;t included that by default. Key association is preserved, just not the ordering.</li>
<li>This only works with strings or integers for keys and values. You could hack together a __toString walk to get it to deal with objects too, and I may do that at some point.</li>
<li>I haven&#8217;t yet benchmarked memory consumption; memory_get_peak_usage doesn&#8217;t seem to work properly with the native array_unique. Help?</li>
<li>For smaller amounts of data (&lt;50k entries) I would suggest keeping array_unique for code-clarity. fast_unique is still faster than array_unique, but at those levels, you&#8217;re talking less than 0.5 seconds difference.</li>
</ol>
<p>To explain how it works, let&#8217;s go through an example: let&#8217;s say we start with this array:</p>
<p><code>0=&gt;apple<br />
1=&gt;biscuit<br />
2=&gt;cabbage<br />
3=&gt;biscuit<br />
</code><br />
When we array_flip it, we try to create an array like this:</p>
<p><code>apple=&gt;0<br />
biscuit=&gt;1<br />
cabbage=&gt;2<br />
biscuit=&gt;3<br />
</code><br />
but now that &#8220;biscuit&#8221; is a key it can&#8217;t have two values, so the &#8220;biscuit=&gt;3&#8243; assignment overwrites the first biscuit value, and we end up with this:</p>
<p><code>apple=&gt;0<br />
biscuit=&gt;3<br />
cabbage=&gt;2<br />
</code><br />
then we flip it again to get key=&gt;value pairs again instead of value=&gt;keys:</p>
<p><code>0=&gt;apple<br />
3=&gt;biscuit<br />
2=&gt;cabbage<br />
</code><br />
And there we go &#8211; duplicates removed! Now in this example, later keys (i.e. 3=&gt;biscuit) overwrote earlier ones (1=&gt;biscuit) &#8211; but with PHP&#8217;s native array_unique earlier keys are preserved, so in the fast_unique function above, we reverse the array before flipping to mimic that functionality &#8211; if you don&#8217;t care about keys then go ahead and strip it out.</p>
<p>I&#8217;ve benchmarked this code for speed against various input sizes: 2k,20k,200k,2m, and various levels of uniqueness: 0%, 50% and 100%. An &#8220;input size&#8221; of 2000 means we fed in an array with 2000 entries whose values are strings between 1 and 200 characters in length. 2 million duplicate entries took too long to generate, so I didn&#8217;t  benchmark that size for the 0% unique test.</p>
<p style="text-align: center;"><img class="aligncenter" title="0% unique data" src="http://www.puremango.co.uk/benchmarks/0pc.png" alt="" width="330" height="273" /></p>
<p style="text-align: center;"><img class="aligncenter" title="50% unique data" src="http://www.puremango.co.uk/benchmarks/50pc.png" alt="" /></p>
<p style="text-align: center;"><img class="aligncenter" title="100% unique data" src="http://www.puremango.co.uk/benchmarks/100pc.png" alt="" /></p>
<p>So there you have it; quite dramatic for large amounts of data. I feel I should mention that the &#8220;double flip&#8221; method is nothing new; there are notes on the PHP docs to the effect that &#8220;the array flip method is faster&#8221;, but I thought a rigorous benchmarking and documentation was worth doing, so please don&#8217;t hate me if you &#8220;invented&#8221; this years ago ;)</p>
<p>Also, if this is the first time you&#8217;ve read about PHP optimisation, do remember that most of the time it&#8217;s pointless trying to speed up PHP code. Array_unique is a special case because it&#8217;s often used on large arrays (and if your array is smaller than around 50k entries, it&#8217;s probably not worth using this function). Read that <a href="http://ilia.ws/files/Dutch_PHP_Conference_2010_OPM.pdf" target="_blank">Common Optimization Mistakes PDF</a>, and my other post on <a href="http://www.puremango.co.uk/2010/04/fast-php/" target="_self">fast PHP</a> for tips on how to correctly approach PHP optimisation.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.puremango.co.uk/2010/06/fast-php-array_unique-for-removing-duplicates/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Caching in Javascript with Cachejs</title>
		<link>http://www.puremango.co.uk/2010/05/caching-in-javascript-with-cachejs/</link>
		<comments>http://www.puremango.co.uk/2010/05/caching-in-javascript-with-cachejs/#comments</comments>
		<pubDate>Tue, 18 May 2010 14:56:07 +0000</pubDate>
		<dc:creator>Howard Yeend</dc:creator>
				<category><![CDATA[javascript]]></category>
		<category><![CDATA[web]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[cache]]></category>
		<category><![CDATA[cachejs]]></category>
		<category><![CDATA[caching]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[developer]]></category>
		<category><![CDATA[Firefox]]></category>
		<category><![CDATA[gg]]></category>
		<category><![CDATA[http]]></category>
		<category><![CDATA[json]]></category>
		<category><![CDATA[lru]]></category>
		<category><![CDATA[memcache]]></category>
		<category><![CDATA[optimisation]]></category>
		<category><![CDATA[performance]]></category>

		<guid isPermaLink="false">http://www.puremango.co.uk/?p=961</guid>
		<description><![CDATA[Here&#8217;s a useful open-source (MIT license) javascript caching object I developed for my job at GG.com, the best horse racing site on the net. (I am contractually obliged to say that every time I mention the URL. Not really though). Like most web applications these days, we make fairly extensive use of Ajax, sending and [...]]]></description>
			<content:encoded><![CDATA[<p>Here&#8217;s a useful open-source (MIT license) javascript caching object I developed for my job at <a href="http://www.gg.com" target="_blank">GG.com, the best horse racing site on the net</a>.<br />
<sup>(I am contractually obliged to say that every time I mention the URL. Not really though).</sup></p>
<p>Like most web applications these days, we make fairly extensive use of Ajax, sending and receiving JSON data across the net on hover events and so on.</p>
<p>However, we&#8217;ve found that all those HTTP requests can slow down the user experience, and causes unnecessary extra load on our application servers, so we decided to employ a client-side Least Recently Used (LRU) caching object, so that we can reduce the number of HTTP requests, and increase the response speed for cachable queries. It employs lazy garbage collection, just like memcached does. In fact we see this as a kind of &#8220;memcache for javascript&#8221;, if that makes any sense at all.</p>
<ul>
<li><strong><a href="http://code.google.com/p/cachejs" target="_blank">Get Cachejs now on Google Code.</a></strong> I&#8217;d love to see what you do with it  ;0)</li>
</ul>
<p>It depends upon no external libraries. Here&#8217;s a simple usage example:</p>
<p><span id="more-961"></span></p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> myCache <span style="color: #339933;">=</span> cache<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #006600; font-style: italic;">// tell the cache to use an array for its internal storage system</span>
myCache.<span style="color: #660066;">setStore</span><span style="color: #009900;">&#40;</span>arrayStore<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// setting a value which does not expire:</span>
<span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span>myCache.<span style="color: #660066;">has</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'foo'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// false</span>
myCache.<span style="color: #660066;">set</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'foo'</span><span style="color: #339933;">,</span><span style="color: #3366CC;">'val'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span>myCache.<span style="color: #660066;">has</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'foo'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// true</span>
<span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span>myCache.<span style="color: #660066;">get</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'foo'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// &quot;val&quot;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// setting a value's expiry:</span>
<span style="color: #003366; font-weight: bold;">var</span> tomorrow <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>
tomorrow.<span style="color: #660066;">setTime</span><span style="color: #009900;">&#40;</span>tomorrow.<span style="color: #660066;">getTime</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #009900;">&#40;</span><span style="color: #CC0000;">1000</span><span style="color: #339933;">*</span><span style="color: #CC0000;">3600</span><span style="color: #339933;">*</span><span style="color: #CC0000;">24</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
myCache.<span style="color: #660066;">setExpiry</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'foo'</span><span style="color: #339933;">,</span>tomorrow<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span>myCache.<span style="color: #660066;">get</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'foo'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// &quot;val&quot; (until tomorrow, then null)</span>
&nbsp;
<span style="color: #006600; font-style: italic;">//deleting from the cache</span>
myCache.<span style="color: #660066;">kill</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'foo'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span>myCache.<span style="color: #660066;">has</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'foo'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// false</span></pre></div></div>

<p>You don&#8217;t need to worry about serialising values; the cache internally json encodes the value if needed when setting, and parses it again before returning it back to you, keeping the interface nice and clean, and allowing you to store any kind of data &#8211; raw JSON, XML, variables, objects, strings, etc.</p>
<p>What&#8217;s more, it&#8217;s designed to be future-proof, with pluggable storage modules allowing you to extend the caching object to use any kind of storage system. The cache API abstracts the storage API away so you can swap stores without changing your caching code at all; you just change the setStore line and the rest of the code will still work just fine.</p>
<p>We&#8217;ve written an <strong>arrayStore</strong> which caches data for the current page only, a <strong>cookieStore </strong>which works for the whole domain but has the usual cookie limits, and a <strong>localstorageStore </strong>which uses the funky <a href="http://dev.w3.org/html5/webstorage/" target="_blank">HTML5 Web Storage specification</a> (AFAIK supported by IE8, FF3.5, Safari4, Chrome4, Opera10).</p>
<p>The full API documentation follows.</p>
<p><strong>Cache API Documentation:</strong></p>
<table>
<tbody>
<tr>
<td width="180">.setStore(store)</td>
<td>store. An <em>uninstantiated</em> object which fulfills the requirements of the store API. Returns TRUE if store was set, else FALSE. The cache will use arrayStore as the default.</td>
</tr>
<tr>
<td width="170">.has(key)</td>
<td>If key exists, returns TRUE, else returns FALSE.</td>
</tr>
<tr>
<td width="170">.kill(key)</td>
<td>Removes key from cache. Returns TRUE if successful, else FALSE.</td>
</tr>
<tr>
<td>.get(key)</td>
<td>If key exists, returns val for key, else returns NULL.</td>
</tr>
<tr>
<td>.set(key, [value [,expiry]])</td>
<td>
<table>
<tbody>
<tr>
<td>key</td>
<td>String. The name of the key.</td>
</tr>
<tr>
<td>val</td>
<td>Mixed. The value of the key. Overwrites previous value if present.<br />
If not set, .get will return NULL for this key and .has will return TRUE.</td>
</tr>
<tr>
<td>expiry</td>
<td><a href="http://www.ietf.org/rfc/rfc1123.txt" target="_blank">RFC1123</a> date. If not set or FALSE, key lasts forever (unless kill or setExpiry subsequently called on this key).</td>
</tr>
</tbody>
</table>
</td>
</tr>
<tr>
<td>.getExpiry(key)</td>
<td>If key exists and is finite, returns <a href="http://www.ietf.org/rfc/rfc1123.txt" target="_blank">RFC1123</a> date, else returns NULL for bad keys, or FALSE for infinite keys</td>
</tr>
<tr>
<td>.setExpiry(key, expiry)</td>
<td>
<table>
<tbody>
<tr>
<td>key</td>
<td>String. The name of the key.</td>
</tr>
<tr>
<td>expiry</td>
<td>Mixed. Either an <a href="http://www.ietf.org/rfc/rfc1123.txt" target="_blank">RFC1123</a> date, or FALSE to set as infinite expiry.</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
<p><strong>Storage API Documentation:</strong><br />
You only need to know about this if you&#8217;re implementing your own stores &#8211; this API is abstracted away in the cache object. If you do want to implement your own stores, I have written some simple javascript unit tests to make sure they comply with the required API.</p>
<table>
<tbody>
<tr>
<td width="180">.has(key)</td>
<td>If key exists, returns TRUE, else returns FALSE</td>
</tr>
<tr>
<td>.get(key)</td>
<td>If key exists, returns val for key, else returns UNDEFINED</td>
</tr>
<tr>
<td>.set(key, [val])</td>
<td>
<table>
<tbody>
<tr>
<td>key</td>
<td>String. The name of the key.</td>
</tr>
<tr>
<td>val</td>
<td>Mixed. The value of the key. Overwrites previous value if present.<br />
If not set, .get will return NULL for this key and .has will return TRUE.</td>
</tr>
</tbody>
</table>
</td>
</tr>
<tr>
<td>.kill(key)</td>
<td>Removes key.</td>
</tr>
</tbody>
</table>
<p>The cache object uses the lovely Module pattern and is well documented. You can download and <a href="http://code.google.com/p/cachejs/" target="_blank">hack it up on google code</a>. Please share your modifications.</p>
<h3>The Future</h3>
<p>What you see above is a pretty simple solution packaged up nicely. I&#8217;d like to see the following features:</p>
<p><strong>Expiry Callback</strong>. So when a key is requested and has expired, it is removed from the store and a callback is executed with the keyname, then the value is checked again and returned. The idea being that the cache can automatically refresh itself when a key expires.</p>
<p><strong>Cache Size Limit</strong>. At the moment the cache will grow arbitrarily large. This could become a problem.</p>
<p><strong>Eager Garbage Collection</strong>. As an option, in case someone finds a use for it. I suspect lazy will be best for most applications though.</p>
<p><strong>Manual Cache Clear</strong>. In case you ever need to manually flush the entire cache.</p>
<p><strong>Helper Methods</strong>. Like .incr(key) to increment a key&#8217;s value, .toJSON(key) to get the JSON&#8217;ed value, .setFromJSON(key,json_val), and probably others. Is this a good idea?</p>
<p><strong>Default Values</strong>. So you can say foo = myCache.get(&#8220;fooKey&#8221;,&#8221;defaultValue&#8221;). Will need to think about how get this working alongside the callback mechanism. I guess we can detect the type of the second argument &#8211; if a function it&#8217;s a callback, else it&#8217;s the default. I want to avoid the second parameter being some json (eg .get(&#8220;fooKey&#8221;, {default: &#8220;def&#8221;, callback: method, expiry: tomorrow}); I find that a little ugly.</p>
<p>If you feel like adding your ideas, features, new stores (ajaxStore?), etc, the MIT license is very open &#8211; far more so than GPL, so hack away at it and let us know what you think!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.puremango.co.uk/2010/05/caching-in-javascript-with-cachejs/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>XKCD Colour Survey &#8211; a 3D visualisation</title>
		<link>http://www.puremango.co.uk/2010/05/xkcd-color-survey-3d-visualization/</link>
		<comments>http://www.puremango.co.uk/2010/05/xkcd-color-survey-3d-visualization/#comments</comments>
		<pubDate>Tue, 04 May 2010 20:48:47 +0000</pubDate>
		<dc:creator>Howard Yeend</dc:creator>
				<category><![CDATA[javascript]]></category>
		<category><![CDATA[machine learning]]></category>
		<category><![CDATA[canvas]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[imagecreate]]></category>
		<category><![CDATA[images]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://www.puremango.co.uk/?p=938</guid>
		<description><![CDATA[Randall Munroe (of XKCD) has been running a &#8220;name the colour&#8221; survey for the last few months and today released the data. The results are broken down by gender, and he makes some fascinating obvservations. I&#8217;ve been working on a colour-related project on and off for about a year now, and part of that has [...]]]></description>
			<content:encoded><![CDATA[<p>Randall Munroe (of <a href="http://www.xkcd.com" target="_blank">XKCD</a>) has been running a &#8220;name the colour&#8221; survey for the last few months and today <a href="http://blog.xkcd.com/2010/05/03/color-survey-results/" target="_blank">released the data</a>. The results are broken down by gender, and he makes some fascinating obvservations.</p>
<p>I&#8217;ve been working on a colour-related project on and off for about a year now, and part of that has involved creating visualisations of the RGB colour space &#8211; plotting red on the X axis, blue on Y, green on Z. So I thought it would be interesting to map XKCD&#8217;s <a href="http://xkcd.com/color/rgb/" target="_blank">954 most common colour names</a> in three dimensions &#8211; his charts are nice n&#8217; all, but sexy javascript 3d is, well, sexier:</p>
<p style="text-align: center;"><a href="http://www.puremango.co.uk/xkcd/xkcd_div.html" target="_blank"><img class="aligncenter" src="http://www.puremango.co.uk/xkcd/xkcd_rgb.png" alt="XKCD Colour Names in 3d" /></a></p>
<p>If you click that, you&#8217;ll be taken to the demo page, where you can interact with the cube. It&#8217;s a bit juddery, working entirely with divs and DOM manipulation, rather than canvas. Here&#8217;s a view from the side angle that shows off the &#8220;3d-ness&#8221; a bit more:</p>
<p><a href="http://www.puremango.co.uk/xkcd/xkcd_div.html" target="_blank"><img class="aligncenter" title="3d vis" src="http://www.puremango.co.uk/xkcd/xkcd_3d.png" alt="" width="568" height="558" /></a></p>
<p>Of course, a canvas is really a better solution, so here&#8217;s a version that renders onto canvas, which is much much faster, but currently omits the names:</p>
<p><span id="more-938"></span></p>
<p><a href="http://www.puremango.co.uk/xkcd/xkcd.html" target="_blank"><img class="alignleft" src="http://www.puremango.co.uk/xkcd/xkcd_rgb_canvas.png" alt="XKCD Colour Names in 3d on a canvas" /></a><a href="http://www.puremango.co.uk/xkcd/xkcd.html" target="_blank"><img class="aligncenter" src="http://www.puremango.co.uk/xkcd/xkcd_rgb_canvas_up.png" alt="XKCD Colour Names in 3d on a canvas" /></a></p>
<p>Again, click for pretty swirlies in anything other than MSIE (updated to include chrome, opera and safari).</p>
<p>In a later blog post, I&#8217;ll be tidying up and releasing the 3d library, which is heavily based on the cunningly named <a href="http://www.wxs.ca/js3d/" target="_blank">JS3D library</a> and I&#8217;ll also be using xkcd&#8217;s data set, among others, to do some really nice machine-learning based image recognition stuff. You&#8217;ll have to wait for all that though.</p>
<p>In the meantime, if anyone wants to pull apart the js3d canvas library I&#8217;ve hacked together from WXS&#8217;s dhtml library and suggest improvements I&#8217;ll be glad to hear them :)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.puremango.co.uk/2010/05/xkcd-color-survey-3d-visualization/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Fast PHP &#8211; effective optimisation and bottleneck detection</title>
		<link>http://www.puremango.co.uk/2010/04/fast-php/</link>
		<comments>http://www.puremango.co.uk/2010/04/fast-php/#comments</comments>
		<pubDate>Sun, 18 Apr 2010 14:42:14 +0000</pubDate>
		<dc:creator>Howard Yeend</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Productivity]]></category>
		<category><![CDATA[web]]></category>
		<category><![CDATA[cache]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[guide]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[plugins]]></category>
		<category><![CDATA[tools]]></category>

		<guid isPermaLink="false">http://www.puremango.co.uk/?p=867</guid>
		<description><![CDATA[PHP is not the fastest language on earth. That honour probably goes to machine code. But like many high-level languages, PHP provides some handy abstractions, like named variables, hashmaps (associative arrays), a C-like syntax, object oriented capabilities, loose typing and so on &#8211; we trade processing speed for development ease. So it&#8217;s quite a common [...]]]></description>
			<content:encoded><![CDATA[<p>PHP is not the fastest language on earth. That honour probably goes to machine code. But like many high-level languages, PHP provides some handy abstractions, like named variables, hashmaps (associative arrays), a C-like syntax, object oriented capabilities, loose typing and so on &#8211; we trade processing speed for development ease.</p>
<p>So it&#8217;s quite a common problem that people find their large PHP web applications running quite slowly.</p>
<p>Here are some frequently encountered bottlenecks found in web applications generally, and PHP specifically:</p>
<p><span id="more-867"></span><strong>1) The Database</strong></p>
<p>So often we treat databases like big persistent arrays. They&#8217;re not.</p>
<p>First of all, remember that anything that goes in or comes out of the DB is going to have to be transferred to your web server. That&#8217;s a network hit. So storing images or other binary data in the database is generally a Bad Idea (for <a href="http://stackoverflow.com/questions/527801/php-to-store-images-in-mysql-or-not" target="_blank">other reasons too</a>). But it&#8217;s not just images &#8211; all database traffic will happen over the local network, so if you&#8217;ve got big chunks of HTML or thousands of rows of data flicking back and forth you need to be aware that that will entail a network hit. mySQL compression can help with this, but be sure to benchmark for your own scripts &#8211; it may be that the CPU overhead cancels out the benefit of mySQL compression for your servers.</p>
<p>Secondly, a great many databases are thrown together without much thought for optimisation. You need to look closely at what queries you&#8217;ll be running, and optimise the structure of the database for them. Often it&#8217;s as simple as adding an index, but sometimes you might need to examine your queries to make sure they&#8217;re doing what they should be.</p>
<p>The database is a very very common source of speed problems &#8211; you will often find that simply adding an index to a table will solve your troubles. Look to the database first!</p>
<p>Here&#8217;s a very neat tip from google&#8217;s <a href="http://code.google.com/speed/articles/optimizing-php.html">php optimisation</a> page:</p>
<blockquote><p><strong>Avoid doing SQL queries within a loop</strong></p></blockquote>
<p>They note that it&#8217;s faster to run one query like this:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> users <span style="color: #66cc66;">&#40;</span>first_name<span style="color: #66cc66;">,</span>last_name<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">VALUES</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;John&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">&quot;Doe&quot;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;Jane&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">&quot;Doe&quot;</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>Than it is to run two queries like this:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> users <span style="color: #66cc66;">&#40;</span>first_name<span style="color: #66cc66;">,</span>last_name<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">VALUES</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;John&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">&quot;Doe&quot;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> users <span style="color: #66cc66;">&#40;</span>first_name<span style="color: #66cc66;">,</span>last_name<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">VALUES</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;Jane&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">&quot;Doe&quot;</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>A great little SQL optimisation tip. Construct one query in a loop and run it once outside the loop rather than running the query inside the loop.</p>
<p><strong>2) Client-side optimisation.<br />
</strong></p>
<p>Often when we hear about &#8220;slow web applications&#8221;, people are actually talking about page load time, which can often be quite independent of the server-side code optimisation side of things. Take a good look at your images &#8211; are they uncompressed PNGs? Do you really lose anything by converting them over to 90% quality JPGs instead? You&#8217;ll certainly gain page load speed and reduce bandwidth. Also make sure you&#8217;re using gzip compression on the web server where applicable, and think about minifying your css, javascript and html code. Often user complaints about sluggish code is actually more related to the delivery rather than the processing. In certain use cases (eg toolbar icons), using CSS sprites is a good client-side optimisation, but don&#8217;t forget about the hit on initial devlopment time.</p>
<p>Install the firebug addons <a href="http://code.google.com/speed/page-speed/" target="_blank">pagespeed</a> and <a href="http://developer.yahoo.com/yslow/" target="_blank">YSlow</a> to get a good look at where the client-side bottlenecks are.</p>
<p><strong>3) Slow Code</strong></p>
<p>PHP is easy. Easy to get wrong that is. There are a lot of posts out there with micro-optimisation techniques, which can work wonders in very specific circumstances, but generally speaking these &#8220;tips&#8221; will be counter-productive in the long run, forcing you to code un-naturally and making your code resistant to changes. For example, using <a href="http://www.phpbench.com/" target="_blank">&amp; to access 1d arrays is faster</a>, but what if you add a dimension later on in development &#8211; will you remember that it hurts performance on &gt;1d arrays? And what if the next version of PHP changes that behaviour?</p>
<p>However, there are a few optimisations that are so blindingly obvious, yet often ignored &#8211; caching the count() in a loop for instance:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">for</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$i</span><span style="color: #339933;">=</span><span style="color: #cc66cc;">0</span> <span style="color: #339933;">;</span> <span style="color: #000088;">$i</span> <span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span> <span style="color: #990000;">count</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$arr</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">;</span> <span style="color: #000088;">$i</span><span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>versus</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">for</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$i</span><span style="color: #339933;">=</span><span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span> <span style="color: #000088;">$c</span><span style="color: #339933;">=</span><span style="color: #990000;">count</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$arr</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">;</span> <span style="color: #000088;">$i</span> <span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span> <span style="color: #000088;">$c</span> <span style="color: #339933;">;</span> <span style="color: #000088;">$i</span><span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>In the first snippet, that count function runs on every iteration. In the second, it runs only once. This really can have a big impact not only on a per-script basis, but also on the server as a whole.</p>
<p>You should really work to make the second style a habit. It&#8217;s hardly any different syntactically but it offers a huge potential performance increase.</p>
<p>But aside from a few simple good practice optimisations like that one, how do you tell where the bottlenecks in your PHP code really are?</p>
<p>A lot of people just throw down echo microtime(); in a bunch of likely-looking places and run it a few times. Let me share a tip about <strong>code profiling</strong>.</p>
<p>Using the <a href="http://xdebug.org/" target="_blank">xdebug extension</a>, we can get an insight into the  speed footprint of every single line of function call in a script. Here&#8217;s an example of the output we can get:</p>
<p><img class="aligncenter" title="winCacheGrind xdebug output" src="http://www.puremango.co.uk/xdebug/xdebug.png" alt="" width="635" height="475" /></p>
<p>We have a nice breakdown of the amount of time (percentage or ms) that each function call takes, how many times it is run, and whether the time is taken up within that function (self) or elsewhere (cumulative). And you can get this breakdown simply by appending ?XDEBUG_PROFILE to the GET request &#8211; no code changes required!</p>
<p>Sadly, there is one caveat: it&#8217;s not very stable on windows. I would moan at you and tell you that you should be developing on the same architecture as your live servers, but as you can clearly see from the screenshot, I&#8217;m still humping Bill Gates too.</p>
<p>Here&#8217;s a little post about <a href="http://elrems.wordpress.com/2008/02/12/profiling-php-with-xdebug-and-wincachegrind/" target="_blank">setting up xdebug and wincachegrind for PHP code profiling</a>. It&#8217;s pretty easy to do.</p>
<p><strong>4) Repeated work is inefficient</strong></p>
<p>So many content managed web applications feature code like this:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">include</span> <span style="color: #0000ff;">&quot;db.php&quot;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">include</span> <span style="color: #0000ff;">&quot;header.php&quot;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$sql</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;SELECT Content FROM Pages WHERE PageID=5&quot;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$res</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_query</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$sql</span><span style="color: #339933;">,</span>CN<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$res</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #000088;">$row</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_fetch_assoc</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$res</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">echo</span> <span style="color: #000088;">$row</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'Content'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;error fetching content&quot;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #b1b100;">include</span> <span style="color: #0000ff;">&quot;footer.php&quot;</span><span style="color: #339933;">;</span></pre></div></div>

<p>And I mean, that&#8217;s one of the nice things about PHP &#8211; you can quickly slap together an interface between the DB and HTML &#8211; wonderful for rapid prototyping.</p>
<p>But think about it &#8211; how often does that page content change? Wouldn&#8217;t it be better to link to page.html, and when the administrator hits save in the backend CMS, overwrite page.html with the generated content?</p>
<p>That way the million users who request that page every month don&#8217;t even spawn a PHP process &#8211; apache can handle that entire transaction. This means the page is served super-quick instead of running the same code with the same input and the same output a million times. Everyone benefits &#8211; the server is running less duplicate code, and users get faster web applications.</p>
<p>It&#8217;s not just rarely-accessed parts of the site that can be optimised in this way either.</p>
<p>Consider an online store. Well, why <em>not</em> generate a pretty much static copy of the site &#8211; it only needs to be updated when product info changes. Obviously you&#8217;ll want to look at your own application to see where it makes sense to cache on the disk instead of generating on-the-fly, but it&#8217;s an option that&#8217;s too often overlooked.</p>
<p>That brings us nicely on to:</p>
<p><strong>5) Caching</strong></p>
<p>This is where the line between web developer and server admin starts to blur, but for large scale applications you will need to start thinking about opcode caching, memcache, squid, mySQL query-cache and other types of cache.</p>
<p>These types of solution are almost always highly tailored to the individual needs of the application, so I will not talk much about it &#8211; the chances are that if you need this level of caching, you already know more about it than I do, so I won&#8217;t pretend to be an expert in this area. Here are some links/pics from the guys who really do know about this kind of stuff:</p>
<ul>
<li><a href="http://blog.reddit.com/2010/03/and-fun-weekend-was-had-by-all.html" target="_blank">Reddit&#8217;s architecture</a></li>
<li><a href="http://www.krisjordan.com/2008/09/18/joe-stump-scaling-digg-and-other-web-applications/" target="_blank">Digg&#8217;s architecture</a></li>
<li><a href="http://upload.wikimedia.org/wikipedia/commons/4/4f/Wikimedia-servers-2009-04-05.svg" target="_blank">Wikipedia&#8217;s architecture</a></li>
<li><a href="http://talks.php.net/show/acc_php/1" target="_blank">Some slides on accelerating PHP</a></li>
</ul>
<p>That&#8217;s all for today. To recap:</p>
<ol>
<li>Don&#8217;t transfer more than you need to across the network.</li>
<li>Make sure your tables are indexed properly.</li>
<li>Don&#8217;t write slow code.</li>
<li>Cache rarely-changing output in files on disk.</li>
<li>Draw out your architecture to identify where more serious caching can happen.</li>
</ol>
<p>Thanks to <a href="http://www.toosweettobesour.com/" target="_blank">Daniel at toosweettobesour</a> for taking me to task about the micro-optimisations ;)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.puremango.co.uk/2010/04/fast-php/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>CSS Gradient Background &#8211; Cross Browser!</title>
		<link>http://www.puremango.co.uk/2010/04/css-gradient/</link>
		<comments>http://www.puremango.co.uk/2010/04/css-gradient/#comments</comments>
		<pubDate>Fri, 02 Apr 2010 12:22:00 +0000</pubDate>
		<dc:creator>Howard Yeend</dc:creator>
				<category><![CDATA[web]]></category>
		<category><![CDATA[chrome]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[developer]]></category>
		<category><![CDATA[Firefox]]></category>
		<category><![CDATA[msie]]></category>
		<category><![CDATA[opera]]></category>
		<category><![CDATA[safari]]></category>

		<guid isPermaLink="false">http://www.puremango.co.uk/?p=883</guid>
		<description><![CDATA[You read that right. This works in: Firefox >=3.6 MSIE &#62;=5.5 (!) Safari >=4 Chrome Oh Em Gee, I&#8217;ve got a CSS-applied Gradient. How neat is this? I mean really, this is super cool. And it degrades gracefully in older browsers and Opera. My boss Mike passed this little CSS gem to me, and now [...]]]></description>
			<content:encoded><![CDATA[<div style="float: left; width: 50%;">
<p>You read that right. This works in:</p>
<ul>
<li>Firefox >=3.6</li>
<li>MSIE &gt;=5.5 (!)</li>
<li>Safari >=4</li>
<li>Chrome</li>
</ul>
</div>
<div class="gradientV" style="float: left; padding: 5px;">
<p>Oh Em Gee, I&#8217;ve got a CSS-applied Gradient.</p>
<p>How neat is this?</p>
<p>I mean really, this is super cool.</p>
</div>
<div style="clear: left;"><!-- --></div>
<p>And it degrades gracefully in older browsers and Opera.</p>
<p>My boss <a href="http://www.merseysideskeptics.org.uk/" target="_blank">Mike</a> passed this little CSS gem to me, and now dear reader I pass it to you. It was orignally developed by <a href="http://blog.fakedarren.com/2010/01/cross-browser-css-gradients/" target="_blank">FakeDarren</a>, who posted a great little CSS button example. I find it useful for those times when designers get all fancy with gradiented backgrounds.</p>
<p>I&#8217;ve condensed Darren&#8217;s CSS down to these four lines plus comments, which will give you the lovely Green-to-Black CSS fade background you can see above.</p>

<div class="wp_syntax"><div class="code"><pre class="css" style="font-family:monospace;">  .gradientV<span style="color: #00AA00;">&#123;</span>
<span style="color: #808080; font-style: italic;">/* thanks to http://blog.fakedarren.com/2010/01/cross-browser-css-gradients/ */</span>
    <span style="color: #808080; font-style: italic;">/* fallback (Opera) */</span>
    <span style="color: #000000; font-weight: bold;">background</span><span style="color: #00AA00;">:</span> <span style="color: #cc00cc;">#008800</span><span style="color: #00AA00;">;</span>
    <span style="color: #808080; font-style: italic;">/* Mozilla: */</span>
    <span style="color: #000000; font-weight: bold;">background</span><span style="color: #00AA00;">:</span> -moz-linear-gradient<span style="color: #00AA00;">&#40;</span><span style="color: #000000; font-weight: bold;">top</span><span style="color: #00AA00;">,</span> <span style="color: #cc00cc;">#00FF00</span><span style="color: #00AA00;">,</span> <span style="color: #cc00cc;">#000000</span><span style="color: #00AA00;">&#41;</span><span style="color: #00AA00;">;</span>
    <span style="color: #808080; font-style: italic;">/* Chrome, Safari:*/</span>
    <span style="color: #000000; font-weight: bold;">background</span><span style="color: #00AA00;">:</span> -webkit-gradient<span style="color: #00AA00;">&#40;</span>linear<span style="color: #00AA00;">,</span>
                <span style="color: #000000; font-weight: bold;">left</span> <span style="color: #000000; font-weight: bold;">top</span><span style="color: #00AA00;">,</span> <span style="color: #000000; font-weight: bold;">left</span> <span style="color: #000000; font-weight: bold;">bottom</span><span style="color: #00AA00;">,</span> from<span style="color: #00AA00;">&#40;</span><span style="color: #cc00cc;">#00FF00</span><span style="color: #00AA00;">&#41;</span><span style="color: #00AA00;">,</span> to<span style="color: #00AA00;">&#40;</span><span style="color: #cc00cc;">#000000</span><span style="color: #00AA00;">&#41;</span><span style="color: #00AA00;">&#41;</span><span style="color: #00AA00;">;</span>
    <span style="color: #808080; font-style: italic;">/* MSIE */</span>
    filter<span style="color: #00AA00;">:</span> progid<span style="color: #3333ff;">:DXImageTransform</span><span style="color: #6666ff;">.Microsoft</span>.Gradient<span style="color: #00AA00;">&#40;</span>
                StartColorStr<span style="color: #00AA00;">=</span><span style="color: #ff0000;">'#00FF00'</span><span style="color: #00AA00;">,</span> EndColorStr<span style="color: #00AA00;">=</span><span style="color: #ff0000;">'#000000'</span><span style="color: #00AA00;">,</span> GradientType<span style="color: #00AA00;">=</span><span style="color: #cc66cc;">0</span><span style="color: #00AA00;">&#41;</span><span style="color: #00AA00;">;</span>
  <span style="color: #00AA00;">&#125;</span></pre></div></div>

<p>And as you may have guessed by the &#8216;V&#8217; in the class name, you can also do horizontal gradients &#8211; here are some more examples for left-right gradients, and we see what happens when we apply animations to a gradiented DIV.<br />
<span id="more-883"></span><br />
Horizontal Gradient CSS:</p>

<div class="wp_syntax"><div class="code"><pre class="css" style="font-family:monospace;">  .gradientH<span style="color: #00AA00;">&#123;</span>
<span style="color: #808080; font-style: italic;">/* thanks to http://blog.fakedarren.com/2010/01/cross-browser-css-gradients/ */</span>
    <span style="color: #808080; font-style: italic;">/* fallback (Opera) */</span>
    <span style="color: #000000; font-weight: bold;">background</span><span style="color: #00AA00;">:</span> <span style="color: #cc00cc;">#008800</span><span style="color: #00AA00;">;</span>
    <span style="color: #808080; font-style: italic;">/* Mozilla: */</span>
    <span style="color: #000000; font-weight: bold;">background</span><span style="color: #00AA00;">:</span> -moz-linear-gradient<span style="color: #00AA00;">&#40;</span><span style="color: #000000; font-weight: bold;">left</span><span style="color: #00AA00;">,</span> <span style="color: #cc00cc;">#00FF00</span><span style="color: #00AA00;">,</span> <span style="color: #cc00cc;">#000000</span><span style="color: #00AA00;">&#41;</span><span style="color: #00AA00;">;</span>
    <span style="color: #808080; font-style: italic;">/* Chrome, Safari:*/</span>
    <span style="color: #000000; font-weight: bold;">background</span><span style="color: #00AA00;">:</span> -webkit-gradient<span style="color: #00AA00;">&#40;</span>linear<span style="color: #00AA00;">,</span>
                <span style="color: #000000; font-weight: bold;">left</span> <span style="color: #000000; font-weight: bold;">top</span><span style="color: #00AA00;">,</span> <span style="color: #000000; font-weight: bold;">right</span> <span style="color: #000000; font-weight: bold;">top</span><span style="color: #00AA00;">,</span> from<span style="color: #00AA00;">&#40;</span><span style="color: #cc00cc;">#00FF00</span><span style="color: #00AA00;">&#41;</span><span style="color: #00AA00;">,</span> to<span style="color: #00AA00;">&#40;</span><span style="color: #cc00cc;">#000000</span><span style="color: #00AA00;">&#41;</span><span style="color: #00AA00;">&#41;</span><span style="color: #00AA00;">;</span>
    <span style="color: #808080; font-style: italic;">/* MSIE */</span>
    filter<span style="color: #00AA00;">:</span> progid<span style="color: #3333ff;">:DXImageTransform</span><span style="color: #6666ff;">.Microsoft</span>.Gradient<span style="color: #00AA00;">&#40;</span>
                StartColorStr<span style="color: #00AA00;">=</span><span style="color: #ff0000;">'#00FF00'</span><span style="color: #00AA00;">,</span> EndColorStr<span style="color: #00AA00;">=</span><span style="color: #ff0000;">'#000000'</span><span style="color: #00AA00;">,</span> GradientType<span style="color: #00AA00;">=</span><span style="color: #cc66cc;">1</span><span style="color: #00AA00;">&#41;</span><span style="color: #00AA00;">;</span>
  <span style="color: #00AA00;">&#125;</span></pre></div></div>

<p>So now we no longer need little 1px slices in the background-image property, just remember to make sure all the colors in each line of CSS match up, and that you choose a nice flat colour fallback that works with your content.</p>
<p>I&#8217;m very impressed with how slim the CSS needs to be to get this great cross-browser CSS background gradient. Just saying those words gives me shivers. Yay for CSS!</p>
<p>One other thing that this allows, which was never possible using css background images, is <em>stretchable gradients</em>. Not only can the content be allowed to expand &#8216;naturally&#8217; via site updates etc, but we can actually animate gradiented DIVs and preserve the effect!</p>
<p>As in:</p>
<div class="gradientV2" onclick="jQuery(this).animate({height:'400px'},1000);">Oh boy, when you click on this, you&#8217;d better be sitting down.</div>
]]></content:encoded>
			<wfw:commentRss>http://www.puremango.co.uk/2010/04/css-gradient/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>Super Useful Web Dev Tools</title>
		<link>http://www.puremango.co.uk/2010/03/super-useful-web-dev-tools/</link>
		<comments>http://www.puremango.co.uk/2010/03/super-useful-web-dev-tools/#comments</comments>
		<pubDate>Wed, 17 Mar 2010 13:25:47 +0000</pubDate>
		<dc:creator>Howard Yeend</dc:creator>
				<category><![CDATA[Firefox]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Productivity]]></category>
		<category><![CDATA[Programs]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[msie]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[regex]]></category>
		<category><![CDATA[tools]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://www.puremango.co.uk/?p=850</guid>
		<description><![CDATA[OMG, it&#8217;s been a whole month since my last update. I have draft posts about all kinds of Good Stuff™, but none are quite publishable yet. So today I&#8217;m just going to point you at a few great resources I use all the time while doing my web development magic: Before I start on the [...]]]></description>
			<content:encoded><![CDATA[<p>OMG, it&#8217;s been a whole month since my last update.</p>
<p>I have draft posts about all kinds of Good Stuff™, but none are quite publishable yet. So today I&#8217;m just going to point you at a few great resources I use all the time while doing my web development magic:</p>
<p><span id="more-850"></span></p>
<p>Before I start on the list proper, I&#8217;m going to assume you already know and love <a href="http://getfirebug.com/" target="_blank">firebug</a>, if not, go away and don&#8217;t come back till you&#8217;ve got it. I mean really, firebug has moved js development forward no end.</p>
<p><strong>Cool (free) Tools That You Need:</strong></p>
<ul>
<li><a href="http://phpjs.org/" target="_blank"><strong>php.js</strong></a> &#8211; a project to port PHP functions to Javascript. Ever wanted to use number_format() in JS? Or date()? Now you can.</li>
<li><a href="http://www.my-debugbar.com/wiki/IETester/HomePage" target="_blank"><strong>IETester</strong></a> &#8211; a program that bundles Internet Explorer 5.5, 6, 7 and 8 together so you can open each one in a new tab and test your website in multiple versions of MSIE.</li>
<li><a href="http://weitz.de/regex-coach/" target="_blank"><strong>The Regex  Coach</strong></a> &#8211; you type the target string, then type the regex. It  highlights the matches as you edit the regex. This will save you hours.</li>
<li><a href="http://home.snafu.de/tilman/xenulink.html" target="_blank"><strong>Xenu</strong></a> &#8211; a program that recursively checks a URL for broken links. This should really be the final stage before go-live of any project.</li>
<li><a href="http://webyog.com/en/" target="_blank"><strong>SQLYog</strong></a> &#8211; like phpMyAdmin in an application, but faster and more robust. Does need the firewall opening up though. Nagware.</li>
<li><a href="http://www.getpaint.net/" target="_blank"><strong>Paint.NET</strong></a> &#8211; If MS Paint and Photoshop had a baby, paint.net would be it. The image editor of choice for those of us who &#8220;just want something a bit better than paint&#8221;.</li>
</ul>
<p>That&#8217;s my list of essentials. Sorry this isn&#8217;t a &#8220;proper&#8221; blog post. Hopefully one or two of the tools there will help you out. The Regex Coach is truly great. And completely compatible with PHP&#8217;s <a href="http://uk3.php.net/manual/en/ref.pcre.php" target="_blank">preg </a>functions (ereg is now deprecated), and javascript regular expressions engine. Yay.</p>
<p>Any &#8220;OMFG I can&#8217;t believe he missed that&#8221; additions? btw, does anyone have a good color picker &#8211; one that I can easily copy the current colour from? Because most of the time I have to just remember that it&#8217;s #FE38C4 or whatever. Being able to Ctrl-C directly would be nice.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.puremango.co.uk/2010/03/super-useful-web-dev-tools/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>

<!-- Dynamic page generated in 1.411 seconds. -->
<!-- Cached page generated by WP-Super-Cache on 2010-09-02 17:54:16 -->
