<?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>Learning the World &#187; yui</title>
	<atom:link href="http://learningtheworld.eu/tag/yui/feed/" rel="self" type="application/rss+xml" />
	<link>http://learningtheworld.eu</link>
	<description></description>
	<lastBuildDate>Tue, 06 Nov 2012 00:17:33 +0000</lastBuildDate>
	<language>en-US</language>
		<sy:updatePeriod>hourly</sy:updatePeriod>
		<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.9.1</generator>
	<item>
		<title>Amazon Machine Tags Plugin for WordPress</title>
		<link>http://learningtheworld.eu/2007/amazon-machine-tags/</link>
		<comments>http://learningtheworld.eu/2007/amazon-machine-tags/#comments</comments>
		<pubDate>Sat, 01 Dec 2007 22:51:26 +0000</pubDate>
		<dc:creator><![CDATA[Martin Kliehm]]></dc:creator>
				<category><![CDATA[downloads]]></category>
		<category><![CDATA[web development]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[Ajax]]></category>
		<category><![CDATA[Amazon]]></category>
		<category><![CDATA[Amazon Web Services]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[AWS]]></category>
		<category><![CDATA[book:isbn=0596515812]]></category>
		<category><![CDATA[book:isbn=0596529260]]></category>
		<category><![CDATA[ECS]]></category>
		<category><![CDATA[i18n]]></category>
		<category><![CDATA[ip2country]]></category>
		<category><![CDATA[machine tags]]></category>
		<category><![CDATA[microformats]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[POSH]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[web services]]></category>
		<category><![CDATA[XSLT]]></category>
		<category><![CDATA[yui]]></category>

		<guid isPermaLink="false">http://learningtheworld.eu/2007/amazon-machine-tags/</guid>
		<description><![CDATA[I always wanted to implement one thing since I started the blog: <strong>a simple inclusion of Amazon items</strong>. I didn&#8217;t want to search through results that existing plugins provided. When I wrote about something like a book, I already used machine tags to identify the subject! So I found the inspiration to write my first real WordPress plugin: Amazon Machine Tags.&#160;[&#8230;]]]></description>
				<content:encoded><![CDATA[<p class="alert">The forthcoming <strong>API change</strong> requiring signed requests will effect this plugin. If you do not <a href="http://wordpress.org/extend/plugins/amazon-machine-tags/">update the plugin</a> then it will stop working on August 15th. Comments on this version are closed, please comment on the <a href="/2009/amazon-authorization/">update page</a>.</p>

<h3>In this article</h3>

<ul class="toc">
<li><a href="#intro">Introduction</a></li>
<li><a href="#installation">Installation</a></li>
<li><a href="#faq"><acronym title="Frequently Asked Questions">FAQ</acronym></a></li>
<li><a href="#changelog">Changelog</a></li>
<li><a href="#comments">Discussion</a></li>
</ul>

<h3 id="intro">Introduction</h3>

<p>I always wanted to implement one thing since I started the blog: <strong>a simple inclusion of Amazon items</strong>. I didn&rsquo;t want to search through results that existing plugins provided. When I wrote about something like a book, I already used machine tags to identify the subject! So I found the inspiration to write my first real WordPress plugin: <a href="http://wordpress.org/extend/plugins/amazon-machine-tags/">Amazon Machine Tags</a>.</p>

<p>Here&rsquo;s what it does:</p>

<ol>
<li>It identifies any tag in the <a href="http://en.wikipedia.org/wiki/Machine_tag">machine (or triple) tag</a> form <code>book:<acronym>isbn</acronym>=1234567890</code> or <code>amazon:asin=1234567890</code>. That works with native tags from WordPress 2.3 and later, Bunny&rsquo;s Technorati Tags, Jerome&rsquo;s Keywords, or as inline text (see below).</li>
<li>Then it gets the <strong>item information and a thumbnail image</strong> from the <a href="http://www.amazon.com/gp/browse.html?node=3435361">Amazon Web Services <acronym title="Application Programming Interface">API</acronym></a>. That&rsquo;s the real thing including prices and such, no cheap <acronym>RSS</acronym> feed. <img src="http://learningtheworld.eu/wp-includes/images/smilies/icon_wink.gif" alt=";)" class="wp-smiley" /> </li>
<li><p>The item(s) are displayed in the sidebar or in a blog article with a link to <strong>the visitor&rsquo;s best match</strong> (if the <a href="http://priyadi.net/archives/2005/02/25/wordpress-ip-to-country-plugin/">ip2country plugin</a> is installed) or <strong>a default Amazon shop</strong> of your choice. See examples in the sidebar.</p>
<p>The &ldquo;best match&rdquo; is based on the visitor&rsquo;s location. If she is from one of the six countries where Amazon has shops, that locale is chosen. If he is from Europe, the preferred language is matched to either France, Germany, or <acronym title="United Kingdom">UK</acronym>, with <acronym>UK</acronym> as default. If it&rsquo;s neither a locale nor Europe, amazon.com is the default. Based on your location, do you think that&rsquo;s a reasonable approach?</p>
<p>Note that some items, like books in any language other than English, are only available from certain locales, so a visitor from the <acronym title="United Kingdom">UK</acronym> might not see German books you recommend.</p></li>
<li>If you are an Amazon Associate for that locale, your Associate ID is included automatically.</li>
</ol>

<p>You can edit the server-side, semantic and valid <acronym title="Extensible Hypertext Markup Language">XHTML</acronym> output via <acronym title="Extensible Stylesheet Language Transformation">XSLT</acronym>, change the <acronym title="Cascading Style Sheets">CSS</acronym>, or translate the admin interface through <a href="http://www.poedit.net">.po files</a>. Actually <strong>Amazon loads the <acronym>XSLT</acronym> file from your server</strong> and processes it on theirs, so you shouldn&rsquo;t block <acronym>HTTP</acronym> access to the plugin directory, and <code>localhost</code> doesn&rsquo;t work either.</p>

<p>Results can be <strong>cached</strong> for anything between one second and one hour, so you don&rsquo;t need to worry even when you run an extremely popular blog.</p>

<p>The <a href="http://developer.yahoo.com/yui/connection/">YUI Connection Manager</a> is included to verify the Access Key in the admin interface via <acronym title="Representational State Transfer">REST</acronym> and unobtrusive <acronym title="Asynchronous JavaScript and XML">AJAX</acronym>.</p>

<p>I hope this little piece of software serves you well and you like it.</p>

<h3 id="installation">Installation</h3>

<ol>
<li><a href="http://downloads.wordpress.org/plugin/amazon-machine-tags.zip">Get the latest version</a> of the plugin from the WordPress site.</li>
<li>Upload the whole <code>amazon-machine-tags</code> folder into the <code>/wp-content/plugins/</code> directory.</li>
<li>Activate the plugin through the &ldquo;Plugins&rdquo; menu in WordPress.</li>
<li>Get an Amazon Web Services <a href="http://docs.amazonwebservices.com/AWSECommerceService/2007-06-13/GSG/GettinganAWSAccessKeyID.html">Access Key</a>.</li>
<li>Create a <code>wp-content/cache/</code> directory with permissions set to 755, or 777 if you create the directory as <code>root</code> user.</li>
<li>Put <code>&lt;?php AMTAP::get_items(); ?&gt;</code> in your sidebar and start using machine tags.</li>
<li><a href="#comment-32667">Edit <code>amtap-blog.css</code></a> if you like.</li>
<li>If you want to use tags in a blog article, write <code>&#91;amtap book:isbn=1234567890&#93;</code> or <code>&#91;amtap amazon:asin=1234567890&#93;</code>. Thanks to <a href="http://www.paulinepauline.de">paulinepauline</a> for that idea.</li>
</ol>

<h3 id="faq">Frequently Asked Questions</h3>

<h4>Does it work in the sidebar on Pages, too?</h4>

<p>Posts have tags, pages don&rsquo;t, so it doesn&rsquo;t work on those by default. But there&rsquo;s a plugin called <a href="http://wordpress.org/extend/plugins/tags4page/">tags4page</a> that enables tags for pages. Works like a charm.</p>

<h4>Is there a limit of how many items can be requested?</h4>

<p>Yes, Amazon has a limit of 10 items per request. Since they are separate requests, you can use a maximum of 10 items in the content plus a maximum of 10 in the sidebar.</p>

<h4>Would it be possible to cache the images?</h4>

<p>Technically it wouldn&rsquo;t be a problem, but the <a href="http://www.amazon.com/AWS-License-home-page-Money/b/?node=3440661#5">Amazon Web Services license</a> explicitly forbids caching of images (see 5.1.10). Sorry.</p>

<h4>I need to a larger thumbnail (medium), but can&rsquo;t seem to find a place to edit the size of the image being requested.</h4>

<p>The image size can be edited in the <acronym title="Extensible Stylesheet Language Transformation">XSLT</acronym>. The original result is a <acronym title="Extensible Markup Language">XML</acronym> file that is transformed by Amazon using your local copy of <code>amtap-html-sidebar.xsl</code> and <code>amtap-html-content.xsl</code>, respectively. Replacing every occurance of <code>.//aws:TinyImage</code> with <code>.//aws:MediumImage</code> should do the trick.
</p>

<p>You can view the original <acronym>XML</acronym> when you activate the &ldquo;debug&rdquo; option in the admin interface so that the request string is printed as a comment in the sidebar&rsquo;s source code. <acronym>XSLT</acronym> is a very powerful tool, and there&rsquo;s a lot more in the <acronym>XML</acronym>, for example customer reviews.</p>

<h4>Are all options really required?</h4>

<p>No. The only required field is the Amazon Web Services Access Key. You can leave the others, they are set to defaults then.</p>

<h3 id="changelog">Changelog</h3>

<ul class="changelog">
<li><strong>3.0</strong> <ins datetime="20090731">(2009-07-31)</ins>: Added signed requests for the new Amazon authorization requirement. Updated the API version to 2009-07-01 (please note: if you use your own XSL files, you must update the version in the XML namespace URL). Updated links.</li>
<li><strong>2.0</strong> <ins datetime="20080718">(2008-07-18)</ins>:
<ol>
<li>Added fields for editing the <a href="http://wppluginreview.info/2008/03/09/review-amazon-machine-tags/">sidebar headline</a>, <a href="#comment-33625">link target</a>, and displaying <a href="#comment-33625">rating stars</a>.</li>
<li>Added an error message if the plugin is run from a private IP address space like <a href="#comment-34319"><code>localhost</code></a>.</li>
<li>Changed <a href="#comment-33888">priorities for price</a> selection, they are now: <code>LowestNewPrice</code>, <code>ListPrice</code>, first offer, <code>LowestUsedPrice</code>.</li>
<li>Added support for the display of an <a href="#comment-34426">artist name</a>.</li>
<li>Added <a href="#comment-34412">rating stars</a>.</li>
<li>Fixed <a href="#comment-34224">EAN numbers with a dash</a>.</li>
<li>Fixed cutting of titles after a <a href="#comment-34326">period</a>.</li>
<li>Changed <acronym title="Cascading Style Sheets">CSS</acronym> and <acronym title="Extensible Stylesheet Language">XSL</acronym> files. <strong>Take care when you edited those.</strong></li>  
</ol>
</li>
<li><strong>1.1.3:</strong> Changed <code>amtap-admin.css</code> and <code>amtap-admin.inc.php</code> to make the admin interface look prettier with WordPress 2.5.</li>
<li><strong>1.1.2:</strong> Fixed a <a href="#comment-33367">bug</a> in <code>amtap.php</code> when there are no other tags but default tags.</li>
<li><strong>1.1.1:</strong> <a href="#comment-32967">Fixed</a> the sort order of inline items, a bug for returning an error message when the cache file is not writable, and added Amazon&rsquo;s limit of 10 items per request.</li>
<li><strong>1.1.0:</strong> Fixed the display of inline tags on the home page. Improved regular expression for filtering inline tags.</li>
<li><strong>1.0.6:</strong> Fixed a bug introduced through the new default items function when there were no items to be displayed in the sidebar.</li>
<li><strong>1.0.5:</strong> Added an option for <a href="#comment-32509">default items on every page</a>. Changed <code>amtap-html-sidebar.xsl</code> to sort items in the order of the request.</li>
<li><strong>1.0.4:</strong> Bugfix for replacement of dollar characters in content. Also content items are now cached separately.</li>
<li><strong>1.0.3:</strong> Fixed the <a href="#comment-32268" title="See comment">display of inline tags</a> on category pages.</li>
<li><strong>1.0.2:</strong> Changed the plugin path from <code>amtap</code> to <code>amazon-machine-tags</code> for consistency with the file structure in the zipped file.</li>
<li><strong>1.0.1:</strong> Bugfix for native WordPress tags.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://learningtheworld.eu/2007/amazon-machine-tags/feed/</wfw:commentRss>
		<slash:comments>202</slash:comments>
		</item>
		<item>
		<title>Website Performance Tweaks, Part Two</title>
		<link>http://learningtheworld.eu/2007/performance-2/</link>
		<comments>http://learningtheworld.eu/2007/performance-2/#comments</comments>
		<pubDate>Sun, 24 Jun 2007 14:20:19 +0000</pubDate>
		<dc:creator><![CDATA[Martin Kliehm]]></dc:creator>
				<category><![CDATA[conferences]]></category>
		<category><![CDATA[web development]]></category>
		<category><![CDATA[@media]]></category>
		<category><![CDATA[atmedia]]></category>
		<category><![CDATA[atmedia07]]></category>
		<category><![CDATA[atmedia2007]]></category>
		<category><![CDATA[book:ean=9780596529307]]></category>
		<category><![CDATA[book:isbn=0596529309]]></category>
		<category><![CDATA[cdn]]></category>
		<category><![CDATA[cpu]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[energy efficiency]]></category>
		<category><![CDATA[etag]]></category>
		<category><![CDATA[expires header]]></category>
		<category><![CDATA[gzip]]></category>
		<category><![CDATA[http-request]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Nate Koechley]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[steve souders]]></category>
		<category><![CDATA[tenni theurer]]></category>
		<category><![CDATA[yahoo]]></category>
		<category><![CDATA[yslow]]></category>
		<category><![CDATA[yui]]></category>

		<guid isPermaLink="false">http://learningtheworld.eu/2007/performance-2/</guid>
		<description><![CDATA[Nate Koechley presented the research results of the Yahoo! Exceptional Performance Team two weeks ago in London. The traditional focus of <strong>performance optimization</strong> has been on the backend, i.e. system efficiency. But comparing a number of high profile websites, the Yahoo! team found that frontend performance is responsible for 80-98% of the perceived response time. Therefore doubling the frontend performance gains more than doubling the backend performance. [&#8230;]]]></description>
				<content:encoded><![CDATA[<p class="vcard"><a href="http://www.flickr.com/photos/drewm/538822354/in/set-72157600330136671/" title="See larger version on flickr"><img alt="Nate Koechley" src="/wp-content/uploads/2007/07/nate-koechley" width="240" height="160" class="floatleft photo" /></a> <strong><a href="http://nate.koechley.com" class="fn url" rel="co-worker met acquaintance">Nate Koechley</a></strong> presented the <a href="http://nate.koechley.com/blog/2007/06/12/high-performance-web-sites">research results</a> of the Yahoo! Exceptional Performance Team two weeks ago in London (<a href="http://www.htmldog.com/atmedia2007/highperformancewebpages.mp3" type="audio/mp3">podcast</a>). Like Yahoo! shares I would like to share that knowledge with you for those who couldn&rsquo;t attend.</p>

<p>The traditional focus of <strong>performance optimization</strong> has been on the backend, i.e. system efficiency. But comparing a number of high profile websites, the Yahoo! team found that frontend performance is responsible for 80-98% of the perceived response time. Therefore doubling the frontend performance gains more than doubling the backend performance. In case studies <em>Yahoo! Search</em> became 40-50% faster, the <em>Yahoo! Mail</em> web application gained 70-100%. Of course there are ways to increase backend performance without throwing in more hardware, but better frontend performance reduces traffic and saves resources.</p>

<p>Saving resources on the <em>client</em> side, particularly <strong>CPU usage</strong>, also pays off in speed. <a href="http://icant.co.uk/sandbox/eventdelegation/">Event delegation</a> is faster than a large number of event handlers. Likewise we know that <a href="/2007/performance/">reducing the number of HTTP requests</a> through techniques like CSS sprites, sliding doors, or file aggregation increases speed. The reason is the limit of two parallel requests <em>per host</em> imposed by HTTP 1.1. That results in a download queue of two requests at a time, increasing the perceived response time of a page. By configuring additional host aliases for your server you can <a href="http://yuiblog.com/blog/2007/04/11/performance-research-part-4/">increase the number of parallel requests</a>&nbsp;&mdash; but more than 2-4 also increase DNS lookups resulting in higher CPU usage and slower response times.</p>

<p>I wonder when Yahoo! will present us another impressive calculation <strong>how many gigawatts have been preserved</strong> by reducing CPU usage in client PCs and in their <a href="http://www.technewsworld.com/story/55792.html" title="Study: Data Center Power Usage Exploding">data</a> <a href="http://brand.yahoo.com/forgood/environment/energy_conservation.html" title="Yahoo! Energy Conservation Program">centers</a>, as one participant asked in the <acronym title="questions and answers">Q&amp;A</acronym> part. <a href="http://www.ecologee.net">Energy efficient servers</a> are the next big thing, but are there any concrete suggestions for <a href="http://www.addsimplicity.com/adding_simplicity_an_engi/2007/01/compute_power_i.html">greener programming</a>? Is <acronym title="Asynchronous JavaScript and XML">AJAX</acronym> destroying the ozone layer? <img src="http://learningtheworld.eu/wp-includes/images/smilies/icon_wink.gif" alt=";)" class="wp-smiley" /> </p>

<p>Environmental issues aside, here&rsquo;s the <strong><a href="http://developer.yahoo.com/performance/rules.html">list of rules</a></strong>. I&rsquo;ll keep it short where I have written about it in <a href="/2007/performance/">my previous article</a>. See the <a href="http://stevesouders.com/hpws/">examples and testcases</a> by Steve Souders.</p>

<ol>
<li id="rule-1"><strong>Make <a href="/2007/performance/">fewer HTTP requests</a>:</strong> This also affects <a href="http://yuiblog.com/blog/2007/03/01/performance-research-part-3/">cookies</a>. Eliminate unnecessary cookies, keep them small, set them at granular domain levels (e.g. <code>finance.yahoo.com</code> instead of <code>.yahoo.com</code>), and set an appropriate Expires date.</li>
<li id="rule-2"><strong>Use a content distribution network (<acronym>CDN</acronym>)</strong> like <a href="http://www.akamai.com">Akamai</a> where your (static) content is served from distributed data centers located nearer to your client. Even if your website is not as big as Google you can profit from faster response times by using the <a href="http://yuiblog.com/blog/2007/02/22/free-yui-hosting"><acronym title="Yahoo! User Interface">YUI</acronym> library&rsquo;s own <acronym>CDN</acronym></a>.</li>
<li id="rule-3"><strong>Add an Expires header</strong> not just <a href="/2007/performance/#enforce-caching" title="Enforce image caching">for images</a>, but also for JavaScript and stylesheet files.</li>
<li id="rule-4"><strong>Enable gzip:</strong> 90%+ of browsers support compression, and <code>gzip</code> is better supported and compresses more than <code>deflate</code>. Gzip <acronym title="Hypertext Markup Language">HTML</acronym> files, <acronym title="Cascading Stylesheets">CSS</acronym>, scripts, <acronym title="Extensible Markup Language">XML</acronym>, <acronym title="JavaScript Object Literal Notation">JSON</acronym>&nbsp;&mdash; <em>no</em> images or <acronym title="Portable Data Format">PDF</acronym>s.</li>
<li id="rule-5"><strong>Put <acronym>CSS</acronym> at the top</strong>, avoid <code>@import</code> as it loads <em>last</em>, even <em>after</em> the images!</li>
<li id="rule-6"><strong>Move scripts to the bottom</strong> as they block parallel downloads even across hostnames and block rendering of any code below them.</li>
<li id="rule-7"><strong>Avoid <acronym>CSS</acronym> expressions</strong> as they execute many times and cost CPU.</li>
<li id="rule-8">
<p><strong>Use external JavaScript and <acronym>CSS</acronym> files.</strong> <a href="/2007/performance/#inline-css">Inline <acronym>CSS</acronym></a> is apparently faster for a user&rsquo;s start page, but not on subsequent pages. After the page has finished loading, use the time to <strong>preload scripts</strong> to speed up secondary pages.</p>
<ol class="code">
<li><code>window.onload = downloadComponents;</code></li>
<li><code>function downloadComponents() {</code></li>
<li class="indent"><code>var elem = document.createElement(&quot;script&quot;);</code></li>
<li class="indent"><code>elem.src = &quot;http://.../file1.js&quot;;</code></li>
<li class="indent"><code>document.body.appendChild(elem);</code></li>
<li><code>}</code></li>
</ol></li>
<li id="rule-9"><strong>Reduce <acronym title="Domain Name Server">DNS</acronym> lookups</strong> for the reasons stated above. Use 1-4 hosts and the <code>keep alive</code> setting.</li>
<li id="rule-10"><strong><a href="/2007/performance/#file-aggregation">Minify JavaScript</a></strong> with JSMin&nbsp;&mdash; inline scripts, too.</li>
<li id="rule-11"><strong>Avoid redirects</strong> as they are the worst form of blocking. Set Expires headers for redirects to enable caching.</li>
<li id="rule-12"><strong>Remove duplicate files:</strong> this is self-explanatory, but it can happen in large teams with many scripts and stylesheets.</li>
<li id="rule-13"><p><strong>Mind the <acronym title="Entity Tag">ETag</acronym>:</strong> Now this was something I never paid attention to. ETags are unique identifiers to distinguish files that share a <acronym title="Uniform Resource Identifier">URI</acronym>. They are transmitted in the HTTP header. The default server setting uses the <a href="http://en.wikipedia.org/wiki/Inode">INode</a>, the bytesize and the modification date of a file to calculate a unique ID. Unless servers in a cluster are identical, ETags differ, therefore the files are <strong>not cached</strong>. Fortunately <a href="http://httpd.apache.org/docs/2.0/mod/core.html#fileetag">ETags can be configured</a> in Apache, so it should be possible to match them across different servers.</p><ol class="code"><li><code>FileETag MTime Size</code></li></ol>
<p>Note that the ETag is also <strong>relevant for <acronym title="Really Simple Syndication">RSS</acronym> feeds</strong>. For example, currently the <a href="http://www.w3.org/2004/08/TalkFiles/Talks.rss" type="application/rss+xml"><acronym title="World Wide Web Consortium">W3C</acronym> talks feed</a> is more or less unusable: some feed readers and services apparently regard the ETag, the feed is mirrored on many servers, so the same news entry from a different server is shown as new and unread multiple times every day&hellip;</p>
</li>
<li id="rule-14"><strong>Make <acronym title="Asynchronous JavaScript and XML">AJAX</acronym> cacheable and small</strong>. Some data like a user&rsquo;s address book or buddy list change infrequently and should be requested via GET, cached, and set with a <code>Last-modified</code> timestamp and gzipped.</li>
</ol>

<p><img src="/wp-content/uploads/2007/06/book-high-performance-web-sites" alt="Book cover: High Performance Web Sites" width="120" height="158" class="floatleft book" /> These are a lot of rules, and they will be published in a O&rsquo;Reilly book by Steve Souders and Tenni Theurer in September 2007. Anyway, don&rsquo;t be overwhelmed by their mass, instead you can start with the easy things: <strong>&ldquo;<q>harvest the low hanging fruit</q>.&rdquo;</strong> Enable caching with the Expire date setting and reduce the number of HTTP requests. You can deal with the rest later.</p>

<p>Finally Nate Koechley announced a Yahoo! performance tool called <strong><a href="http://developer.yahoo.com/yslow/">YSlow</a></strong> as a plugin for the indespensible <a href="http://www.getfirebug.com">Firebug</a> extension. He also recommended the commercial <a href="http://alphaworks.ibm.com/tech/pagedetailer">IBM Page Detailer</a>, and <a href="http://livehttpheaders.mozdev.org">LiveHTTPHeaders</a> to visualize what&rsquo;s happening in your browser.</p>
]]></content:encoded>
			<wfw:commentRss>http://learningtheworld.eu/2007/performance-2/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
<enclosure url="http://www.htmldog.com/atmedia2007/highperformancewebpages.mp3" length="26276424" type="audio/mpeg" />
		</item>
		<item>
		<title>Graded Browser Support Q2 Update</title>
		<link>http://learningtheworld.eu/2007/graded-browser-support-q2-update/</link>
		<comments>http://learningtheworld.eu/2007/graded-browser-support-q2-update/#comments</comments>
		<pubDate>Tue, 08 May 2007 14:30:41 +0000</pubDate>
		<dc:creator><![CDATA[Martin Kliehm]]></dc:creator>
				<category><![CDATA[web development]]></category>
		<category><![CDATA[browser]]></category>
		<category><![CDATA[browser support]]></category>
		<category><![CDATA[browsers]]></category>
		<category><![CDATA[graded browser support]]></category>
		<category><![CDATA[Nate Koechley]]></category>
		<category><![CDATA[yahoo]]></category>
		<category><![CDATA[yui]]></category>

		<guid isPermaLink="false">http://learningtheworld.eu/2007/graded-browser-support-q2-update/</guid>
		<description><![CDATA[Based on Nate Koechley&#8217;s concept of graded browser support we terminated support for Firefox&#160;1.5 because it&#8217;s no longer supported and upgraded by Mozilla. Also we changed Opera support from 9.0 to 9.x, where &#8220;x&#8221; stands for the latest stable version.&#160;[&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Based on <a href="http://nate.koechley.com/blog/" rel="colleague met">Nate Koechley&rsquo;s</a> concept of <strong><a href="http://developer.yahoo.com/yui/articles/gbs/gbs.html">graded browser support</a></strong> we terminated support for Firefox&nbsp;1.5 because it&rsquo;s no longer supported and upgraded by Mozilla. Also we changed Opera support from 9.0 to 9.x, where &ldquo;x&rdquo; stands for the latest stable version.</p>

<h3 id="bluemars-matrix">Matrix of supported browsers in BlueMars projects</h3>

<table cellspacing="0" cellpadding="0" class="gbs">
                    <tbody>
                        <tr class="first">
                            <td></td>
                            <th scope="col">Windows XP</th>
                            <th scope="col"><abbr title="Macintosh OS v10.4 Tiger">Mac 10.4</abbr></th>
                            <th scope="col"><abbr title="Debian Linux">Linux</abbr></th>
                        </tr>
                        <tr>
                            <th scope="row"><abbr title="Internet Explorer 7">IE 7.0</abbr></th>
                            <td class="a">A-grade</td>
                            <td class="na">n/a</td>
                            <td class="na">n/a</td>
                        </tr>
                        <tr>
                            <th scope="row"><abbr title="Internet Explorer 6.0 Service Pack 2">IE 6.0</abbr></th>
                            <td class="a">A-grade</td>
                            <td class="na">n/a</td>
                            <td class="na">n/a</td>
                        </tr>
                        <tr>
                            <th scope="row"><abbr title="Internet Explorer 5.5">IE 5.5</abbr></th>
                            <td class="c">C-grade</td>
                            <td class="na">n/a</td>
                            <td class="na">n/a</td>
                        </tr>
                        <tr>
                            <th scope="row"><abbr title="Internet Explorer 5.01 Service Pack 2">IE 5.0</abbr></th>
                            <td class="c">C-grade</td>
                            <td class="dead">&dagger;</td>
                            <td class="na">n/a</td>
                        </tr>
                        <tr>
                            <th scope="row"><abbr title="Mozilla Firefox 2.0, latest version">Firefox 2.0.x</abbr></th>
                            <td class="a">A-grade</td>
                            <td class="a">A-grade</td>
                            <td class="a">A-grade</td>
                        </tr>
                        <tr>
                            <th scope="row"><abbr title="opera 9, latest version">Opera 9.x</abbr></th>
                            <td class="a">A-grade</td>
                            <td class="x">X-grade</td>
                            <td class="x">X-grade</td>
                        </tr>
                        <tr>
                            <th scope="row"><abbr title="Safari 2, latest version">Safari 2.0.x</abbr></th>
                            <td class="na">n/a</td>
                            <td class="a">A-grade</td>
                            <td class="na">n/a</td>
                        </tr>
                        <tr>
                            <th scope="row"><abbr title="Konqueror, latest Version">Konqueror 3.5.x</abbr></th>
                            <td class="na">n/a</td>
                            <td class="na">n/a</td>
                            <td class="a">A-grade</td>
                        </tr>
                    </tbody>
                </table>
]]></content:encoded>
			<wfw:commentRss>http://learningtheworld.eu/2007/graded-browser-support-q2-update/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Website Performance Tweaks</title>
		<link>http://learningtheworld.eu/2007/performance/</link>
		<comments>http://learningtheworld.eu/2007/performance/#comments</comments>
		<pubDate>Thu, 25 Jan 2007 20:00:35 +0000</pubDate>
		<dc:creator><![CDATA[Martin Kliehm]]></dc:creator>
				<category><![CDATA[downloads]]></category>
		<category><![CDATA[web development]]></category>
		<category><![CDATA[book:isbn=0596529309]]></category>
		<category><![CDATA[cache]]></category>
		<category><![CDATA[caching]]></category>
		<category><![CDATA[concat]]></category>
		<category><![CDATA[css sprites]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[Douglas Crockford]]></category>
		<category><![CDATA[Ed Eliot]]></category>
		<category><![CDATA[file aggregation]]></category>
		<category><![CDATA[http-request]]></category>
		<category><![CDATA[JSMin]]></category>
		<category><![CDATA[mozilla]]></category>
		<category><![CDATA[Nate Koechley]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[sliding doors]]></category>
		<category><![CDATA[techniques]]></category>
		<category><![CDATA[yahoo]]></category>
		<category><![CDATA[yui]]></category>

		<guid isPermaLink="false">http://learningtheworld.eu/2007/performance/</guid>
		<description><![CDATA[In the last six months I became more aware of techniques for optimizing website performance. I learned about memory leaks and JavaScript performance, but what impressed me most was Nate Koechleyâ€™s presentation about large scale website performance issues in â€œYahoo! <abbr title="versus">vs.</abbr> Yahoo!&#8221; at the @media conference 2006. In the meantime there have been more blog posts about particular aspects of performance optimization, so I wrote a summary.&#160;[&#8230;]]]></description>
				<content:encoded><![CDATA[<p>In the last six months I became more aware of techniques for <strong>optimizing website performance</strong>. I learned about <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/IETechCol/dnwebgen/ie_leak_patterns.asp" title="Microsoft Developer Network: Understanding and solving Internet Explorer leak patterns">memory</a> <a href="http://outofhanwell.com/ieleak/" title="Drip: A memory leak detector for Internet Explorer">leaks</a> and <a href="http://blogs.msdn.com/ie/archive/2006/08/28/728654.aspx" title="IE + JavaScript performance recommendations &ndash; part 1">JavaScript</a> <a href="http://blogs.msdn.com/ie/archive/2006/11/16/ie-javascript-performance-recommendations-part-2-javascript-code-inefficiencies.aspx" title="IE + JavaScript performance recommendations &ndash; part 2">performance</a>, but what impressed me most was <a href="http://nate.koechley.com/blog/2006/07/12/my_atmedia_2006_slides/" rel="met colleague">Nate Koechley&rsquo;s presentation</a> about large scale website performance issues in &ldquo;<a href="http://learningtheworld.eu/2006/atmedia-day-two/#koechley" title="See my notes about his talk">Yahoo! <abbr title="versus">vs.</abbr> Yahoo!</a>&rdquo; at the @media conference 2006. In the meantime there have been more blog posts about particular aspects of performance optimization, and I&rsquo;d like to sum them up:</p>

<p id="file-location"><strong>Parsing JavaScript</strong> freezes the browser. Therefore put <acronym title="Cascading Stylesheets">CSS</acronym> in the <code>head</code> and JavaScript near to the <code>&lt;/body&gt;</code> so that it is parsed when the page has been rendered.</p>

<p id="http-requests">The arch enemy of performance are <strong><a href="http://yuiblog.com/blog/2006/11/28/performance-research-part-1/" title="YUI Blog: Performance research &ndash; what the 80/20 rule tells us about reducing HTTP requests"><acronym title="Hypertext Transfer Protocol">HTTP</acronym> requests</a></strong>. Many browsers still can&rsquo;t handle more than two or four requests at a time. Keep the number of files down, your website will be faster.</p>

<p>There are several techniques with the aim to reduce the number of files:</p>

<ol><li id="inline-css"><p><strong>&ldquo;<q>A single large file is fastest.</q>&rdquo;</strong> (<cite>Nate Koechley</cite>) That&rsquo;s why Yahoo! <em>apparently</em> has such an amount of <a href="http://www.robertnyman.com/2007/01/24/with-these-web-sites-would-you-say-the-web-standards-war-is-won/">inline <acronym title="Cascading Stylesheets">CSS</acronym></a>. They found out <a href="http://yuiblog.com/blog/2007/01/04/performance-research-part-2/" title="YUI Blog: Performance research, part 2: browser cache usage &ndash; exposed!">browser caching</a> is not as effective as they thought, in particular not on a user&rsquo;s start page. So they deliver &ldquo;inline&rdquo; <acronym>CSS</acronym>. Actually writing inline <acronym>CSS</acronym> is a maintenance nightmare, but delivering <acronym>CSS</acronym> content inline doesn&rsquo;t mean the files can&rsquo;t have separate lives on the server: concatenate the files with a server side technique of your choice.</p>
<p><strong>Update:</strong> A couple of months later <a href="/2007/performance-2/#rule-8">Nate explained that further</a>: when your page is likely to be a user&rsquo;s start page, caching plays a minor role, thus &ldquo;inline&rdquo; <acronym>CSS</acronym> is faster. Otherwise use external files, aggregate them, and make sure they are cached (see below).</p></li>
<li id="enforce-caching"><p><strong>Enforce caching.</strong> Another <a href="http://www.bazon.net/mishoo/articles.epl?art_id=958"><acronym title="Internet Explorer">IE</acronym> bug</a> prevents image caching. Add the following to your <code>.htaccess</code>, <code>httpd.conf</code> or <code>vhost.conf</code> settings:</p>
<ol class="code">
<li><code>&lt;IfModule mod_expires.c&gt;</code></li>
<li class="indent"><code>ExpiresActive On</code></li>
<li class="indent"><code>ExpiresByType image/jpg &quot;access plus 1 day&quot;</code></li>
<li class="indent"><code>ExpiresByType image/jpeg &quot;access plus 1 day&quot;</code></li>
<li class="indent"><code>ExpiresByType image/gif &quot;access plus 1 day&quot;</code></li>
<li class="indent"><code>ExpiresByType image/png &quot;access plus 1 day&quot;</code></li>
<li><code>&lt;/IfModule&gt;</code></li></ol></li>
<li id="background-images"><p><strong>Reduce the number of background images</strong> with techniques like <a href="http://www.alistapart.com/articles/sprites/">CSS Sprites</a> or <a href="http://www.alistapart.com/articles/slidingdoors/">Sliding Doors</a>. Instead of four images of rounded corners you <a href="http://www.fiftyfoureleven.com/sandbox/sliding-doors-one-image/" title="Example">only need one</a> and get the mouseover state for free! The green download button on <a href="http://www.mozilla.com">mozilla.com</a> is based on that technique. And <a href="http://www.yahoo.com">Yahoo!</a> uses <acronym>CSS</acronym> Sprites to combine a huge number of icons.</p>

<p><img src="/wp-content/uploads/2007/01/mozilla-button.jpg" class="centered screenshot" width="300" height="149" alt="Download button on mozilla.com using the Sliding Doors technique" /></p>

<p>Please note this approach is only for <em>decorational background images</em> that degrade gracefully. <del>It&rsquo;s not for <code>img</code> elements.</del> <ins>Be careful when you use it for <a href="/2007/foreground-sprites/">foreground images</a>.</ins> And if text comes as a graphical representation, it can become inaccessible for screen reader users, zoom readers, or people with stylesheets switched off. Use real text instead.</p>

<p>Also note changing the <code>background-position</code> causes <acronym>IE6</acronym> to flicker, related to the caching bug above. To avoid it, simply add the following:</p>
<ol class="code">
<li><code>&lt;script type=&quot;text/javascript&quot;&gt;</code></li>
<li class="indent"><code>try { document.execCommand(<span class="codeSpace">&nbsp;</span>&quot;BackgroundImageCache&quot;, false, true); } catch(e) {};</code></li>
<li><code>&lt;/script&gt;</code></li></ol></li>
<li id="file-aggregation"><p><strong>Aggregate files.</strong> Ed Eliot wrote a nice <a href="http://www.ejeliot.com/blog/72" title="Automatic merging and versioning of CSS/JS files with PHP">script to merge JavaScript or <acronym>CSS</acronym> files</a>, bonus respect for the advanced versioning and caching features.</p>

<p>But remember the cases when it doesn&rsquo;t make sense to merge <acronym>CSS</acronym> files: your <acronym title="Internet Explorer">IE</acronym> bugfixes still belong in conditional comments. If you use the <code>@import</code> rule to filter antique browsers from getting advanced styles, you can&rsquo;t drop it. And if you want to merge stylesheets for different media (<abbr title="for example">e.g.</abbr> print), make sure the code is enclosed in something like</p>


<ol class="code">
<li><code>@media print {</code></li>
<li class="indent"><code>/* style sheet for print goes here */</code></li>
<li><code>}</code></li></ol>


<p>In an <a href="http://www.ejeliot.com/blog/73" title="Adding JSMin to the CSS/JS merging script">updated version</a> Ed added <a href="http://javascript.crockford.com/jsmin.html">JSMin</a> to strip comments and excess whitespace. JSMin works like a charm for JavaScript files. But it cuts a few space characters too much so that the syntax of <acronym>CSS</acronym> selectors changes <del>therefore for now I have abandoned the idea to compress them too</del>. <ins>See <a href="#comment-6045">Jens Meiert&rsquo;s comment</a> below for a recommendation to minimize <acronym>CSS</acronym>.</ins></p>

<p>His original code requires the C version of JSMin with PHP <code>safe_mode</code> turned off. If you prefer a pure PHP version, get the <a href="http://javascript.crockford.com/jsmin2.php.txt">PHP version of JSMin</a> and my <a href="/examples/combine-jsmin.phps" type="text/plain">adapted version of the script</a>.</p>
</li></ol>

<p>I&rsquo;m still in awe how fast one of my own websites became! Thanks to the guys at Yahoo! for the inspiration and for most of the research this article is based upon. Even JSMin was written by an employee of Yahoo! Speaking about Yahoo! employees: <a href="http://wait-till-i.com/" title="Christian Heilmann" rel="met colleague">Chris</a>, I hope there are still enough topics for your <a href="http://www.thinkvitamin.com/features/dev/enhance-your-page-performance" title="Chris Heilmann: Enhance your (page) performance!">Vitamin article</a>. I wanted to write about performance anyway, and to my surprise I <a href="http://www.robertnyman.com/2007/01/24/with-these-web-sites-would-you-say-the-web-standards-war-is-won/#comment-29959">read yesterday</a> that you have similar plans. See ya in <a href="/2007/brain-food/#e-accessibility" title="First European e-Accessibility Forum">Paris</a>. <img src="http://learningtheworld.eu/wp-includes/images/smilies/icon_wink.gif" alt=";)" class="wp-smiley" /> </p>
]]></content:encoded>
			<wfw:commentRss>http://learningtheworld.eu/2007/performance/feed/</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
		<item>
		<title>Graded Browser Support Q4 Update</title>
		<link>http://learningtheworld.eu/2006/graded-browser-support-q4-update/</link>
		<comments>http://learningtheworld.eu/2006/graded-browser-support-q4-update/#comments</comments>
		<pubDate>Tue, 28 Nov 2006 17:00:05 +0000</pubDate>
		<dc:creator><![CDATA[Martin Kliehm]]></dc:creator>
				<category><![CDATA[web development]]></category>
		<category><![CDATA[browser]]></category>
		<category><![CDATA[browser support]]></category>
		<category><![CDATA[browsers]]></category>
		<category><![CDATA[graded browser support]]></category>
		<category><![CDATA[Nate Koechley]]></category>
		<category><![CDATA[yahoo]]></category>
		<category><![CDATA[yui]]></category>

		<guid isPermaLink="false">http://learningtheworld.eu/2006/graded-browser-support-q4-update/</guid>
		<description><![CDATA[Nate Koechley introduced Yahoo!&#8217;s smart concept of <a href="http://developer.yahoo.com/yui/articles/gbs/gbs.html">graded browser support</a> nine months ago. Until then we did test on a lot of browsers, but all browsers were supported equal. Now came this man who suggested distinctions... Almost unnoticed were <strong>two updates</strong> of the browser matrix in August and a couple of days ago.&#160;[&#8230;]]]></description>
				<content:encoded><![CDATA[<blockquote cite="http://developer.yahoo.com/yui/articles/gbs/gbs.html">
<p>&ldquo;Expecting two users using different browser software to have an identical experience fails to embrace or acknowledge the heterogeneous essence of the Web.&rdquo;</p>
</blockquote>

<p class="vcard"><a href="http://nate.koechley.com/blog/" class="url fn" rel="colleague met">Nate Koechley</a> introduced Yahoo!&rsquo;s smart concept of <strong><a href="http://developer.yahoo.com/yui/articles/gbs/gbs.html">graded browser support</a></strong> nine months ago. Until then we did test a lot of browsers, but all browsers were supported equal. Now came this man who suggested distinctions, a <em>graded</em> instead of a boolean or binary support.</p>

<ul>
<li><p>There is a blacklist of <strong>C-grade</strong> browsers. They are antiquated, but <strong>core</strong> content and functionality should work in them. Never mind the design though, as some of them do not support <acronym title="Cascading Style Sheets">CSS</acronym>&nbsp;2. Semantics and good accessibility are more important and tested by <acronym title="Quality Assurance">QA</acronym>.</p></li>
<li><p>Then there is a whitelist of <strong>advanced (A-grade)</strong> browsers supporting modern web standards. <acronym title="Quality Assurance">QA</acronym> tests these browsers, and bugs are handled with high priority.</p></li>
<li><p>The rest of the unknown or rare browsers are <strong>X-grade</strong>. It is assumed they support modern web standards, but it would be inefficient and impossible to test them.</p></li>
</ul>

<p>That&rsquo;s a very <a href="http://yuiblog.com/blog/2006/11/15/browser-support-update-2006q4/#comment-15788" title="Nate Koechley about cost benefits">pragmatic and efficient</a> framework since it adds scalability for <acronym title="Quality Assurance">QA</acronym>.</p>

<p>Almost unnoticed were <strong>two updates</strong> of the browser matrix in <a href="http://yuiblog.com/blog/2006/08/18/browser-support-update-2006q3/" title="Graded Browser Support Q3 Update">August</a> and a <a href="http://yuiblog.com/blog/2006/11/15/browser-support-update-2006q4/" title="Graded Browser Support Q4 Update">couple of days ago</a> where Opera&nbsp;8 got replaced by Opera&nbsp;9, also support for Internet Explorer 5.5, Safari&nbsp;1 and Firefox&nbsp;1.0 has been discontinued because they are vanishing species. Support for Firefox 2.0 has been added, while Mozilla suite has been terminated since there are virtually no differences between Firefox and Mozilla suite.</p>

<p>Our own matrix includes Konqueror, but otherwise it&rsquo;s more or less the same as the current <a href="http://developer.yahoo.com/yui/articles/gbs/gbs_browser-chart.html">Yahoo! browser matrix</a>, although we do not test rare Windows versions like Windows 98 or 2000. Here is the adapted matrix we use in our own projects. Do you think that&rsquo;s a reasonable approach?</p>

<h3 id="bluemars-matrix">Matrix of supported browsers in BlueMars projects</h3>

<table cellspacing="0" cellpadding="0" class="gbs">
                    <tbody>
                        <tr class="first">
                            <td></td>
                            <th scope="col">Windows XP</th>
                            <th scope="col"><abbr title="Macintosh OS v10.4 Tiger">Mac 10.4</abbr></th>
                            <th scope="col"><abbr title="Debian Linux">Linux</abbr></th>
                        </tr>
                        <tr>
                            <th scope="row"><abbr title="Internet Explorer 7">IE 7.0</abbr></th>
                            <td class="a">A-grade</td>
                            <td class="na">n/a</td>
                            <td class="na">n/a</td>
                        </tr>
                        <tr>
                            <th scope="row"><abbr title="Internet Explorer 6.0 Service Pack 2">IE 6.0</abbr></th>
                            <td class="a">A-grade</td>
                            <td class="na">n/a</td>
                            <td class="na">n/a</td>
                        </tr>
                        <tr>
                            <th scope="row"><abbr title="Internet Explorer 5.5">IE 5.5</abbr></th>
                            <td class="c">C-grade</td>
                            <td class="na">n/a</td>
                            <td class="na">n/a</td>
                        </tr>
                        <tr>
                            <th scope="row"><abbr title="Internet Explorer 5.01 Service Pack 2">IE 5.0</abbr></th>
                            <td class="c">C-grade</td>
                            <td class="dead">&dagger;</td>
                            <td class="na">n/a</td>
                        </tr>
                        <tr>
                            <th scope="row"><abbr title="Mozilla Firefox 2.0, latest version">Firefox 2.0.x</abbr></th>
                            <td class="a">A-grade</td>
                            <td class="a">A-grade</td>
                            <td class="a">A-grade</td>
                        </tr>
                        <tr>
                            <th scope="row"><abbr title="Mozilla Firefox 1.5, latest version">Firefox 1.5.x</abbr></th>
                            <td class="a">A-grade</td>
                            <td class="a">A-grade</td>
                            <td class="a">A-grade</td>
                        </tr>
                        <tr>
                            <th scope="row"><abbr title="Mozilla Firefox 1.0.7">Firefox 1.0.7</abbr></th>
                            <td class="x">X-grade</td>
                            <td class="x">X-grade</td>
                            <td class="x">X-grade</td>
                        </tr>
                        <tr>
                            <th scope="row">Opera 9.0</th>
                            <td class="a">A-grade</td>
                            <td class="x">X-grade</td>
                            <td class="x">X-grade</td>
                        </tr>
                        <tr>
                            <th scope="row"><abbr title="Safari 2, latest version">Safari 2.0.x</abbr></th>
                            <td class="na">n/a</td>
                            <td class="a">A-grade</td>
                            <td class="na">n/a</td>
                        </tr>
                        <tr>
                            <th scope="row"><abbr title="Konqueror, latest Version">Konqueror 3.5.x</abbr></th>
                            <td class="na">n/a</td>
                            <td class="na">n/a</td>
                            <td class="a">A-grade</td>
                        </tr>
                    </tbody>
                </table>
]]></content:encoded>
			<wfw:commentRss>http://learningtheworld.eu/2006/graded-browser-support-q4-update/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
