<?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>muhuk.com &#187; performance</title>
	<atom:link href="http://www.muhuk.com/tag/performance/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.muhuk.com</link>
	<description>know thyself</description>
	<lastBuildDate>Thu, 02 Sep 2010 07:13:59 +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>Web Site Performance Optimizations</title>
		<link>http://www.muhuk.com/2010/02/web-site-performance-optimizations/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=web-site-performance-optimizations</link>
		<comments>http://www.muhuk.com/2010/02/web-site-performance-optimizations/#comments</comments>
		<pubDate>Mon, 22 Feb 2010 12:01:43 +0000</pubDate>
		<dc:creator>Atamert Ölçgen</dc:creator>
				<category><![CDATA[Internet]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[http]]></category>
		<category><![CDATA[optimization]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://www.muhuk.com/?p=342</guid>
		<description><![CDATA[Recently I have done some optimizations to make telvee a little faster using django_compressor and making sprites for background images. Good news is substantial changes to development environment and the design wasn&#8217;t required. I&#8217;ll get into details below. But first I&#8217;d like to write about the theory a little bit. I follow (and read with [...]]]></description>
			<content:encoded><![CDATA[<p>Recently I have done some optimizations to make <a href="http://www.telvee.com">telvee</a> a little faster using <a href="http://github.com/muhuk/django_compressor">django_compressor</a> and making sprites for background images. Good news is substantial changes to development environment and the design wasn&#8217;t required. I&#8217;ll get into details below. But first I&#8217;d like to write about the theory a little bit.</p>

<p>I follow (and read with great interest) Steve Souders&#8217;s blog <a href="http://www.stevesouders.com/blog/">High Performance Web Sites</a>. I must admit I was sceptical about it at first; spriting images, individual different loading behaviours of browsers&#8230; I thought they were <a href="http://en.wikipedia.org/wiki/Program_optimization">premature optimization</a>s. But I realized I was wrong as I continued to read. Steve Souders is an expert on high performance web sites and what he preaches are realistic techniques, backed by test results most of the time. If you are not following, I suggest you add it to your RSS reader.</p>

<h3>Optimization Techniques</h3>

<p>We can explore the techniques in two main categories:</p>

<ol>
<li>Techniques to reduce the data to be transferred.

<ul>
<li><strong>Minifying</strong>: Minification is removing comments and unneeded whitespace in CSS and JavaScript files. Compilers like <a href="developer.yahoo.com/yui/compressor/">YUI Compressor</a> and <a href="code.google.com/closure/">Closure</a> modifies JavaScript code to compress even further, without any changes to the functionality.</li>
<li><strong>Gzipping</strong>: Web browsers accept <a href="http://en.wikipedia.org/wiki/Gzip#Other_uses">gzip</a> encoded content for a long time. I have just compressed a 13 KB text file down to 4 KB. A two thirds compression ratio is not bad at all.</li>
</ul></li>
<li>Techniques to reduce the number of HTTP requests.

<ul>
<li><strong>Combining</strong>: CSS and JavaScript files can be combined together into a single file and therefore a single HTTP request. Gzip may be more efficient on these files. In a similar way background images can be merged into a <a href="http://en.wikipedia.org/wiki/Sprite_%28computer_graphics%29#Application">sprite</a> and then reconstructed again using their coordinates on that sprite.</li>
<li><strong>Data URI&#8217;s</strong>: Images (or other file types) can be embedded into CSS (or JavaScript or HTML) using <a href="http://en.wikipedia.org/wiki/Data_URI_scheme"><code>data: URI</code>&#8216;s</a>. Extra HTTP requests for those resources can be avoided this way.</li>
</ul></li>
</ol>

<p>You might think <em>it&#8217;s fine to perform all these optimizations, but what happens when I want to make some changes to my combined, minified JavaScript file?</em> Instead of applying these techniques blindly, it&#8217;s best to follow a sensible plan for implementing these optimizations:</p>

<ul>
<li>First of all <em>everything that can be automated should be automated</em>. Regarding the example above script files should stay uncombined and uncompressed in the development environment and optimizations should be applied when the application is published. Taking it a step further we can have the application detect changes in those files and update optimized versions automatically. (django&#95;compressor works this way)</li>
<li>I was worried that spriting would complicate managing the design. But I have seen, on the contrary; if images each sprite contain are choosen carefully it makes the process easier. Start combining images that belong to the same design element. Avoid complex arrangements, stick with horizontal or vertical stacking as much as possible. Don&#8217;t forget to leave transparent spaces between items and sprite border. Try to combine images that are loaded on the same page, avoid loading a sprite for only half of it&#8217;s elements. Don&#8217;t force yourself to combine all images, if you follow the guidelines I have mentione they won&#8217;t.</li>
<li>When performing optimizations don&#8217;t forget to use easily available tools. You can use <a href="http://developer.yahoo.com/yslow/">YSlow</a> for general analysis, <a href="http://spriteme.org/">SpriteMe</a> for image combining tips, <a href="http://compressorrater.thruhere.net/">CompressorRater</a> to compare different compilers&#8217; performance on your scripts. I would like to note that Steve Souders is the developer of first two.</li>
</ul>

<h3>Telvee Results</h3>

<p>I didn&#8217;t think about performance at all when I started developing <a href="http://www.telvee.com">telvee</a>. Too many CSS files and too many images were being loaded. Here is what it looked like before optimizations:</p>

<table>
  <tr><th>&nbsp;</th><th># of requests</th><th>load (KB)</th></tr>
  <tr><th>Homepage</th><td>25</td><td>~85</td></tr>
  <tr><th>Cup Detail</th><td>48</td><td>~80</td></tr>
</table>

<p>Then I have installed and configured <a href="http://github.com/muhuk/django_compressor">django_compressor</a>. I used YUI Compressor for both JavaScript and CSS. I have created sprites and modified CSS files manually<sup>1</sup>. Then I deployed these changes and measured again:</p>

<table>
  <tr><th>&nbsp;</th><th># of requests</th><th>load (KB)</th></tr>
  <tr><th>Homepage</th><td>12</td><td>~70 (~160)</td></tr>
  <tr><th>Cup Detail</th><td>14</td><td>~64</td></tr>
</table>

<p>In the load column of Homepage, the number in parens is the actual load. But the design of homepage is changed with this upgrade and a new 90 KB image is being loaded now. So I have accepted 70 KB in my calculations. The result of optimizations are as follows:</p>

<table>
  <tr><th>&nbsp;</th><th># of requests</th><th>load (KB)</th></tr>
  <tr><th>Homepage</th><td>52%</td><td>17%</td></tr>
  <tr><th>Cup Detail</th><td>70%</td><td>19%</td></tr>
</table>

<h3>Django&#95;compressor and Data URI&#8217;s</h3>

<p>Django&#95;compressor, developed by Christian Metts, helps you to apply optmizations I have mentioned above easily to your <a href="http://www.djangoproject.com/">Django</a> projects. You can see my fork <a href="http://github.com/muhuk/django_compressor">here</a> where I have merged some other branches and added a little bit of code myself.</p>

<p>Using <code>compressor.filters.datauri.CssDataUriFilter</code> in <code>data-uri</code> branch of this repository, you can embed linked files within your CSS files. It will only embed files less than or equal to 1024 Bytes (1 KB) by default. You can change this limit by setting <code>COMPRESS_DATA_URI_MIN_SIZE</code> in your <code>settings.py</code>.</p>

<p>There are a couple of things to pay attention when you convert your references to <code>data: URI</code>s. Firstly file contents are <code>base64</code> encoded which means approximately one third increase in size. It&#8217;s up to you to balance between increased bandwidth and reduced request counts<sup>2</sup>. Another thing to watch for is multiple references to the same file will end up embedding the same data many times. The solution to this problem is to reduce all references to one<sup>3</sup> but this might break your CSS arrangement strategy.</p>

<p>Please test django&#95;compressor&#8217;s <code>data: URI</code> support and tell me what you think. If you haven&#8217;t applied optimizations I mentioned above, you should. Thanks to django&#95;compressor they are quite easy to implement on Django projects.</p>

<hr />

<p><strong>1</strong>: I would like to add automatic sprite building/linking support to django&#95;compressor sometime.</p>

<p><strong>2</strong>: With Today&#8217;s modern connections 1~2 KB increase is a good price for 1 less HTTP request..</p>

<p><strong>3</strong>: <a href="http://meiert.com/en/blog/20090401/why-css-needs-no-variables/">http://meiert.com/en/blog/20090401/why-css-needs-no-variables/</a></p>


<p>Related posts:<ol><li><a href='http://www.muhuk.com/2009/05/sad-state-of-web-development-industry-in-turkiye/' rel='bookmark' title='Permanent Link: Sad State of Web Development Industry in Türkiye'>Sad State of Web Development Industry in Türkiye</a></li>
<li><a href='http://www.muhuk.com/2009/03/django-where-should-my-app-live/' rel='bookmark' title='Permanent Link: Django: Where Should My App Live'>Django: Where Should My App Live</a></li>
<li><a href='http://www.muhuk.com/2009/07/django-testing-with-file-system-side-effects/' rel='bookmark' title='Permanent Link: Django: Testing With File System Side Effects'>Django: Testing With File System Side Effects</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.muhuk.com/2010/02/web-site-performance-optimizations/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>
