<?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>DQuinn.net &#187; javascript</title>
	<atom:link href="http://www.dquinn.net/tags/javascript/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.dquinn.net</link>
	<description>Daniel J. Quinn&#039;s journal of WordPress, electronic publishing, and general geek culture.</description>
	<lastBuildDate>Thu, 22 Jul 2010 23:46:09 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Three Sexy Performance Rules for .htaccess on WordPress: Configure ETags, Gzip Compression, and Expires Headers</title>
		<link>http://www.dquinn.net/htaccess-adding-etags-gzip-expires-headers/</link>
		<comments>http://www.dquinn.net/htaccess-adding-etags-gzip-expires-headers/#comments</comments>
		<pubDate>Wed, 22 Apr 2009 15:40:15 +0000</pubDate>
		<dc:creator>Daniel Quinn</dc:creator>
				<category><![CDATA[WordPress]]></category>
		<category><![CDATA[.htaccess]]></category>
		<category><![CDATA[animalcules]]></category>
		<category><![CDATA[cache-control header]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[dynamic images]]></category>
		<category><![CDATA[etags]]></category>
		<category><![CDATA[facelift image replacement]]></category>
		<category><![CDATA[flir]]></category>
		<category><![CDATA[gzip]]></category>
		<category><![CDATA[homunculi]]></category>
		<category><![CDATA[ie6]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[mediatemple]]></category>
		<category><![CDATA[mod_deflate]]></category>
		<category><![CDATA[mod_gzip]]></category>
		<category><![CDATA[netscape]]></category>
		<category><![CDATA[opera]]></category>
		<category><![CDATA[sifr 3]]></category>
		<category><![CDATA[wp super cache]]></category>
		<category><![CDATA[yahoo]]></category>
		<category><![CDATA[yslow]]></category>

		<guid isPermaLink="false">http://www.dquinn.net/?p=1450</guid>
		<description><![CDATA[<p>For those of us cheapskates on shared servers, our greatest weapon against the admonitions of YSlow is .htaccess, that innocuous text file that has the capacity to blow up your website if you mistreat it. To defeat rules #3: Add an Expires or Cache-Control Header, #4 GZip Components, and #13 Configure ETags, we need the following .htaccess swank.</p>]]></description>
			<content:encoded><![CDATA[<p>For those of us cheapskates on shared servers, our greatest weapon against the admonitions of YSlow is .htaccess, that innocuous text file that has the capacity to blow up your website if you mistreat it.</p>
<p>To defeat rules #3: <strong>Add an Expires or Cache-Control Header</strong>, #4 <strong>GZip Components</strong>, and #13 <strong>Configure ETags</strong>, we need the following .htaccess swank (thanks to <a href="http://www.reelseo.com">Matt Robertson</a> for noticing that the rules I had here were not compressing CSS or JS):</p>
<pre class="brush: plain;">
# MOD_DEFLATE COMPRESSION
SetOutputFilter DEFLATE

# 1-WEEK EXPIRES HEADER
ExpiresActive On
ExpiresDefault A0
ExpiresDefault A604800
Header append Cache-Control &quot;public&quot;

# PUT YOUR WP SUPER CACHE RULES HERE

# KILL THEM ETAGS
FileETag none

# YOUR WORDPRESS PRETTY PERMALINK RULES GO HERE
</pre>
<h2>GZip Compression</h2>
<p>In the above, I use mod_deflate compression because I'm hosted on MediaTemple, which doesn't offer gzip compression. The rules turn on mod_deflate for my CSS and Javascript because I'm also using <a href="http://wordpress.org/extend/plugins/wp-super-cache/">WP Super Cache</a>, which handles compression for everything else. In tandem with WP Super Cache, everything on my site is gzipped, and therefore YSlow gives me an A for rule #4.</p>
<p>If you don't have the mod_deflate module on your shared space, you likely have mod_gzip enabled, so use that:</p>
<pre class="brush: plain;">
# IF YOU CAN'T USE MOD_DEFLATE...
mod_gzip_on Yes
mod_gzip_dechunk Yes
mod_gzip_item_include file .(html?|txt|css|js|php|pl)$ mod_gzip_item_include handler ^cgi-script$
mod_gzip_item_include mime ^text/.* mod_gzip_item_include mime ^application/x-javascript.*
mod_gzip_item_exclude mime ^image/.* mod_gzip_item_exclude rspheader ^Content-Encoding:.*gzip.*
</pre>
<p>This won't work on a variety of ancient browsers (pre-IE6, Opera 5, and Netscape, for example), but of course, who the hell cares.</p>
<h2>Expires Headers</h2>
<p>The idea here is that if you tell the browser the lifespan of your assets, the browser will keep them in its cache longer, which means your readers will be able to browse faster, from page to page, after they've downloaded your assets after the initial page load. Sounds a bit sketchy at first, but then I remembered that most people never CTRL+click Refresh or bother clearing their cache, so we can rely on their laziness.</p>
<p>My example above expires just about any kind of asset 1 week after it's downloaded, but keep in mind that you have <a href="http://www.askapache.com/htaccess/speed-up-your-site-with-caching-and-cache-control.html">a lot of options</a> when it comes to assigning these lifespans. It really depends on how often you change your content on your end.</p>
<h3>Assigning Dynamic Images Cache Control Headers in FLIR</h3>
<p>After much Interweb soul-searching, I decided that FLIR, the <a href="http://facelift.mawhorter.net/detailed-examples/">Facelift Image Replacement Method</a>, is the best image replacement method out there (for my purposes, at least). I used <a href="http://novemberborn.net/sifr3">sIFR 3</a> for a long time to render fancy fonts on my site, but every day when I looked at myself in the mirror, I was ashamed, among other things, for having to resort to Flash for such a trivial task. I intend to write an article about image replacement methods and the reason why I ultimately decided upon FLIR, so more on this later, but the point of my bringing this up is that the <a href="http://wordpress.org/extend/plugins/facelift-image-replacement/">Facelift Image Replacement WordPress Plugin</a> (which forks off the real FLIR) generates dynamic images for fonts, but doesn't assign them cache-control headers.</p>
<p>Hours of Googling landed me on <a href="http://forums.mawhorter.net/viewtopic.php?id=157">this page</a>. Here the author provides a solution to the problem. He writes:</p>
<blockquote><p>New user visits a brand new uncached image, it is generated.  They refresh the page, another request is probably made and a 304 not modified is returned.  You're right, this is unnecessary.</p>
<p>I think by adding a cache-control to the output_file function the images would then get cached by the browser without causing an extra call to verify that it hasn't been modified.  This should stop a lot of unnecessary trips to the server.</p></blockquote>
<p>The corresponding file in the Facelift plugin is inc-flir.php, located in the plugin's /facelift/ folder. Scroll down to line 395, and add the following:</p>
<pre class="brush: php;">
/* add this line */
header('Cache-Control: max-age=1209600, public, must-revalidate');

/* before the following lines */
header('Last-Modified: '.gmdate('D, d M Y H:i:s GMT', $ts));
header('ETag: &quot;'.md5($ts).'&quot;');
</pre>
<p>Adjust the expiration time to your liking. Now YSlow won't complain that the dynamic images generated by FLIR have no cache-control headers.</p>
<h2>ETags</h2>
<p>Last but not least (well yes, maybe least), the mystical "entity tags." These little things creep me out like Leeuwenhoek's animalcules or <em>FMA</em>'s homunculi. To paraphrase Yahoo, Etags are just doodads that servers and browsers use to check if the assets in the browser cache match up with original assets from the server. In the <a href="http://developer.yahoo.net/blog/archives/2007/07/high_performanc_11.html">performance rules</a>, Yahoo gripes about ETags because they don't quite do what they're supposed to do if your site pulls its assets from multiple servers. Of course, the vast majority of websites aren't doing this because the vast majority of website owners are cheapskates. Nevertheless, YSlow will give us a big fat F if we try to actually configure ETags "correctly." Since there's little space left in our brains to debate such nonsense, Yahoo instructs us to simply turn the little entities off. And frankly, my dear, I don't give a damn.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dquinn.net/htaccess-adding-etags-gzip-expires-headers/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
		<item>
		<title>Nobody Wants to See Your Whitespace: Minify CSS and Javascript using Yahoo!&#8217;s UI Compressor</title>
		<link>http://www.dquinn.net/minify-css-javascript-yui-compressor/</link>
		<comments>http://www.dquinn.net/minify-css-javascript-yui-compressor/#comments</comments>
		<pubDate>Tue, 21 Apr 2009 12:41:07 +0000</pubDate>
		<dc:creator>Daniel Quinn</dc:creator>
				<category><![CDATA[WordPress]]></category>
		<category><![CDATA[comments]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[minification]]></category>
		<category><![CDATA[minified]]></category>
		<category><![CDATA[minify]]></category>
		<category><![CDATA[obfuscated]]></category>
		<category><![CDATA[open source community]]></category>
		<category><![CDATA[yahoo!'s ui compressor]]></category>

		<guid isPermaLink="false">http://www.dquinn.net/?p=1477</guid>
		<description><![CDATA[Beating rule #10 is easy. We want to serve CSS and Javascript that has been minified (and obfuscated, if you please) to our readers, because that's less overhead for them to download. We also want to do it without screwing up our code, so I recommend using Yahoo!'s UI Compressor.]]></description>
			<content:encoded><![CDATA[<p>Beating rule #10 is easy. We want to serve CSS and Javascript that has been minified (and obfuscated, if you please) to our readers, because that's less overhead for them to download. We also want to do it without screwing up our code, so I recommend using <a href="http://developer.yahoo.com/yui/compressor/">Yahoo!'s UI Compressor</a>.</p>
<p>Now, would-be ultra-"l33t" programmers might enjoy using a command line, but I sure don't. It's a waste of the time Darwinian evolution spent on developing my eyeballs. Instead, swing on by to this cool guy's website, <a href="http://refresh-sf.com/yui/">http://refresh-sf.com/yui/</a>, where you can just copy paste your CSS or JS into a text field and get it minified/obfuscated without fiddling with Stone Age command prompts.</p>
<p>What happens when we have to make changes to our files after they've been minified/obfuscated? Since I don't use a fancy development environment to handle my files, I just minify/obfuscate the files that are up on the server and leave my local files alone. If I need to make a quick CSS change, I make them locally and just find/replace the same lines on the server. Janky? Yes. Not ideal? Sure. But it works.</p>
<p>* <em>Keep one thing in mind when you minify/obfuscate</em>: comments get stripped out entirely, and usually the software license or developer credit for freeware is contained in those comments. After some meditation on this matter, I decided that it's silly to keep the comments in after minification; that would be doing it half-assed and ultimately it defeats the purpose. As a compromise, we should have a page in our website that credits the creator of source code we borrow from the open source community. This provides even more visibility for our open source colleagues while allowing us to fully minify our files.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dquinn.net/minify-css-javascript-yui-compressor/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
