tag:www.haslindsayachievedworlddominationyet.com,2008:/posts linz.id.au 2011-02-08T00:53:26-05:00 Enki Lindsay Evans linz@linz.id.au tag:www.haslindsayachievedworlddominationyet.com,2008:Post/20 2011-02-08T00:53:00-05:00 2011-02-08T00:53:26-05:00 Setting HTTP headers on CSS fonts for great justice (and performance) <p>Some tips for configuring your web server for optimum performance when using <a href="https://developer.mozilla.org/en/css/@font-face"><span class="caps">CSS</span> fonts</a> (&#8217;@font-face&#8217;, as some would call it).</p> <p>1. Certain types of font files don&#8217;t have any sort of compression in the actual file, so <a href="http://developer.yahoo.com/performance/rules.html#gzip">your web server should be configured to serve them up compressed</a>. Compressing the font files can give significant file size savings, Museo Sans weighs in at 48KB for the <span class="caps">TTF</span> version, gzip compression drops this to 26KB. Compressing <span class="caps">SVG</span> can give even greater savings &#8211; from 53KB down to 15KB.</p> <p>2. Setting a <a href="http://developer.yahoo.com/performance/rules.html#expires">far future Expires header</a> for font files will make them cachable &#38; reduce <span class="caps">HTTP</span> requests on subsequent visits.</p> <p>3. In addition, not having the correct content type can cause display issues (i.e. they don&#8217;t display at all).</p> This handy table summarises what is what: <table> <thead> <tr> <th>Name</th> <th>Extension</th> <th>Compressed file?</th> <th>Content type</th> </tr> </thead> <tbody> <tr> <td><span class="caps">EOT</span></td> <td>.eot</td> <td>yes</td> <td>application/vnd.ms-fontobject</td> </tr> <tr> <td>TrueType</td> <td>.ttf</td> <td>no</td> <td>font/ttf</td> </tr> <tr> <td>OpenType</td> <td>.otf</td> <td>no</td> <td>font/opentype</td> </tr> <tr> <td><span class="caps">WOFF</span></td> <td>.woff</td> <td>yes</td> <td>font/x-woff</td> </tr> <tr> <td><span class="caps">SVG</span></td> <td>.svg</td> <td>no</td> <td>image/svg+xml</td> </tr> </tbody> </table> <p>Clear as mud? Okay, let&#8217;s move on to&#8230;</p> <h2>Configuring the server</h2> <p>Three things need to be done: - enable gzip compression for the non-compressed fonts (TTF, <span class="caps">OTF</span> &#38; <span class="caps">SVG</span>) - add correct content types for all font types - add far future expires header for all font files</p> <p>Configuration for specific servers will differ, but <a href="https://gist.github.com/794800">these should get you started</a>:</p> <p><b>Apache 2:</b></p> <script src="https://gist.github.com/794800.js?file=.htaccess"></script> <p><b><span class="caps">IIS7</span>:</b></p> <script src="https://gist.github.com/794800.js?file=web.config"></script> <p><b>Nginx:</b></p> <script src="https://gist.github.com/794800.js?file=nginx.conf"></script> <p>This doesn&#8217;t cover all the other juicy bits you can do to improve performance when using <span class="caps">CSS</span> fonts &#8211; removing kerning, subsetting, base64 encoding, etc. &#8211; these will be dependent on your own personal preferences &#38; the needs of your particular project.</p> tag:www.haslindsayachievedworlddominationyet.com,2008:Post/19 2010-12-19T19:19:00-05:00 2010-12-19T19:45:04-05:00 Impact of attribute order on compression <p>One of my personal coding standards is to keep similar <span class="caps">HTML</span> attributes grouped together in a consistent order at the start of the element, e.g.</p><table class="CodeRay"><tr> <td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"><pre>1<tt> </tt>2<tt> </tt></pre></td> <td class="code"><pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }">&lt;script type=&quot;text/javascript&quot; src=&quot;foo&quot;&gt;&lt;/script&gt;<tt> </tt>&lt;script type=&quot;text/javascript&quot; src=&quot;bar&quot;&gt;&lt;/script&gt;<tt> </tt></pre></td> </tr></table> <p>vs.</p><table class="CodeRay"><tr> <td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"><pre>1<tt> </tt>2<tt> </tt></pre></td> <td class="code"><pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }">&lt;script src=&quot;foo&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;<tt> </tt>&lt;script src=&quot;bar&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;<tt> </tt></pre></td> </tr></table> <p>This helps with readability, maintainability, &amp;c. &amp;c.</p> <p>Recently another thought occurred to me: that this would also help with <span class="caps">HTTP</span> compression.</p> <p>I ran a quick test using these two (very simplified) <span class="caps">HTML</span> documents:</p> <script src="https://gist.github.com/747837.js?file=ordered.html"></script> <noscript><a href="https://gist.github.com/747837.js?file=ordered.html">ordered.html</a></noscript> <script src="https://gist.github.com/747837.js?file=unordered.html"></script> <noscript><a href="https://gist.github.com/747837.js?file=unordered.html">unordered.html</a></noscript> <p>With the following results (taken from the Firebug Net panel):</p> <table> <tr> <th>File</th> <th>Size<br>(uncompressed)</th> <th>Size<br>(compressed)</th> </tr> <tr> <td>ordered.html</td> <td>240b</td> <td>145b</td> </tr> <tr> <td>unordered.html</td> <td>240b</td> <td>148b</td> </tr> </table> <p>So, the ordered version gives us a saving of 3 bytes &#8211; not a massive gain, but in a much larger document it could be significant.</p> <p>I imagine this would also hold true (and possibly give much more significant savings) for <span class="caps">CSS</span> if property/value pairs that are the same are grouped together.</p> <p>For those of you interested in such things, I tested the compressed vs. uncompressed <span class="caps">HTML</span> by first soft linking the <span class="caps">HTML</span> files:</p> <pre><code>ln -s ordered.html ordered-uncompressed.html ln -s unordered.html unordered-uncompressed.html</code></pre> <p>The adding the following .htaccess:</p> <pre><code>AddOutputFilterByType DEFLATE text/html SetEnvIfNoCase Request_URI uncompressed no-gzip dont-vary</code></pre> <p>which disables output compression for any <span class="caps">URI</span> that contains &#8216;uncompressed&#8217;.</p> tag:www.haslindsayachievedworlddominationyet.com,2008:Post/18 2009-03-28T12:00:00-04:00 2009-06-05T18:54:14-04:00 Redesign in progress <p>I’ve finally started doing the redesign I’ve been <a href="/2008/08/31/linz-id-au-now-with-more-enki">promising for so long</a>.</p> <p>It’s not finished yet, so if you whinge about it not working in whatever stupid browser you’re using then I’ll just laugh at you :p</p> <p><span class="caps"><span class="caps">TODO</span></span>: <ul> <li>Finish the background (cloning &#38; dodging &#38; burning etc. to make it tile horizontally)</li> <li>Get the skipnav thinger workign better</li> <li>Funky JavaScript animation</li> <li>Print <span class="caps"><span class="caps">CSS</span></span></li> <li>Sekrit awesome stuff that will blow your freakin mind (if I ever finish it)</li> <li>Spinning bits</li> <li>Bacon</li> </ul></p> Fun bits: <ul> <li>Using <span class="caps"><span class="caps">HTML5</span></span> properly (aww yeah)</li> <li>Liquidy-proportional-whatever layout so you can stalk me on your iPhone or your 36inch 29000×4282 monitor or whatever</li> </ul> tag:www.haslindsayachievedworlddominationyet.com,2008:Post/17 2008-11-12T12:00:00-05:00 2009-06-05T18:53:27-04:00 Spinning Flaming Skull <p><a rel="external" href="http://spinningflamingskull.com/">Spinning Flaming Skull</a> was created to fill a gaping void that existed on teh interwebs – until December 9th 2008 there did not exist an animated gif of a skull that both span and was on fire.</p> <p>And turn your speakers up, the soundtrack rocks!</p> tag:www.haslindsayachievedworlddominationyet.com,2008:Post/16 2008-11-09T12:00:00-05:00 2009-06-05T18:51:48-04:00 Webjam 8 <p><a rel="external" href="http://webjam.com.au/">Webjam</a> is back!</p> <p><a rel="external" href="http://webjam.com.au/webjam8">Webjam 8</a> is on Thursday the 25<sup>th</sup> of September, just after the first day of <a rel="external" href="http://south08.webdirections.org/">Web Directions South ‘08</a>.</p> <p>I may even present <a rel="external" href="http://whatcheesesyouoff.com/">What Cheeses You Off?</a> if you’re lucky.</p>