CastlesBlog.com

a blog about a blog

Subscribe

Cookieless Domain

Update

There has been a few updates to the new template to fix some errors plus I've given Opera some love. The CSS background gradient is the only feature missing from Opera and while I could get it working with a background image the alternative looks fine. I'm sure the folks at Opera are working on CSS gradient support and it will be available soon.

Opera Screenshot

PageSpeed & Yslow

One of the main features I want to highlight with CastlesBlog is speed. I found the results were pretty good after inspecting PageSpeed and Yslow but there were a few optimisations that could be made.

Tip: PageSpeed and Yslow are fantastic Firebug addons and are great tools if you want to dig deep into a websites rendering speed.

The main issue that they highlighted was to put my static content on a cookieless domain. I've never done anything like this before and I didn't even know what cookieless domain was. Read about it here. After a bit of investigating I think I worked it out. Here is my understanding: When you create a cookie on a site the cookie information is transmitted and received with every request. That means every image, css or javascript file that doesn't actually need the information will get it and send it. Now I know your thinking that fairly trivial as cookies are generally tiny and not worth the hassle. I agree! Especially on this site which doesn't get the amount of traffic or have enough resources to warrant such optimisations. The problem for me was that I was intrigued and that sent me on a journey to work out how to actually get a cookieless domain working.

From what I read you can avoid sending cookies if you setup a separate domain or CNAME and serve the content from there.

Tip: I found myself using cookies and I didn't even know it. Calling session_start(); in php will set a PHPSESSID cookie.

What is a CNAME?

From Wikipedia:

A CNAME record or Canonical Name record is a type of resource record in the Domain Name System (DNS) that specifies that the domain name is an alias of another, canonical domain name.

So basically I could setup a CNAME that points to www.castlesblog.com and serve static resources from there. I wouldn't have to change the structure of my site and old content would still work fine. Sounds good to me.

To setup in Plesk I did the following:

  1. Click on DNS Settings
  2. Click Add Record
  3. Select CNAME record type
  4. Enter the domain name I wanted to use. I chose to use "static" (static.castlesblog.com)
  5. Finally, enter the canonical name of the domain. For me I used www.castlesblog.com
  6. Click Ok and then Save

One other thing I needed to do to get this to work in Plesk was to create a vhost.conf file in the domain conf directory (/var/www/vhosts/castlesblog.com/conf/vhost.conf) with the following content: "ServerAlias static.castlesblog.com" then reconfigure that domain:

/usr/local/psa/admin/sbin/websrvmng --reconfigure-vhost --vhost-name=castlesblog.com

The last thing I needed to do was update all my posts and html links to the static domain. For example the following:

<img src="/data/img1.jpg" />

would become:

<img src="http://static.castlesblog.com/data/img1.jpg" />

To prevent people browsing the secondary domain I setup a .htaccess redirect to redirect any non file requests to the proper domain. The code looks like this:

# cookieless domain for images and stuff
RewriteCond %{HTTP_HOST} ^static\.castlesblog\.com [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ http://www.castlesblog.com/$1 [R=301,L]

Serve dynamic-static files

One final optimisation was to serve javascript as one file to save browser requests. I like to separate javascript files so that it obvious what is in them so I wasn't going to move all the javascript into one file. I managed to get the merge working with the following code:

<?php
$offset = 60 * 60 * 24 * 7; // Cache for 1 weeks
header('Content-type: application/x-javascript');
header('Accept-Ranges: bytes');
header ('Cache-Control: max-age=' . $offset);
header ('Expires: ' . gmdate ("D, d M Y H:i:s", time() + $offset) . ' GMT');
header ('Pragma: cache');

if(!ob_start("ob_gzhandler")) ob_start();

include('../javascript/jquery-1.4.2.min.js');
include('../javascript/jquery.easing.js');
include('../templates/castlesblog/template.js');

When a site needs a new javascript file I will include it in this file and the php will do the rest.

To make the script tag look like this:

<script src="http://static.castlesblog.com/javascript/scripts.js" type="text/javascript"></script>

I added the following to the .htaccess:

#compile all scripts into one file...
RewriteRule ^javascript/scripts.js$ includes/scripts.php [L]

Final Test

To see if this works I will include the same file from two different domains. This first file should have cookies and the second should not.

iPhone PreviewiPhone Preview

And the results are in.. I think they speak for themselves:

cookieless domain results

Comments:

  1. Martin Brown - 22nd June 2010

    Thanks - good article. A couple of things I came across though. On my server the default cookie domain was .domain.com so cookies were still being served on the static subdomain. This was resolved by adding the following to .htaccess: php_value session.cookie_domain "www.domain.com" Also google analytics was creating .domain.com cookies by default as well so the domain must be set there as well: _gaq.push(["_setDomainName", "www.domain.com"]);

Post Comment