I was reading in Google\'s documentation about improving site speed. One of their recommendations is serving static content (images, css, js, etc.) from a \"cookieless domai
This is how I've done in my website:
your.domain.com
domain.com
or else the sub-domain will not be cookielessStatic
Static
folder created earlier.static.domain.com
Not enabled
.Now you have a static website. To setup open the web.config
file under Static
folder and replace with this one:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.web>
<sessionState mode="Off" />
<pages enableSessionState="false" validateRequest="false" />
<roleManager>
<providers>
<remove name="AspNetWindowsTokenRoleProvider" />
</providers>
</roleManager>
</system.web>
<system.webServer>
<staticContent>
<clientCache cacheControlMode="UseMaxAge" cacheControlMaxAge="30.00:00:00" />
</staticContent>
<httpProtocol>
<customHeaders>
<remove name="X-Powered-By" />
</customHeaders>
</httpProtocol>
</system.webServer>
</configuration>
This is going to cache the files for 30 days, remove a RoleManager (I don't know if it changes anything but I removed all I could find), and remove an item from Response Headers.
But here is a problem, your content will be cached even when a new version is deployed, so to avoid this I made an helper method for MVC. Basically you have to append some QueryString that will change every time you change these files.
default.css?v=1 ?v=2 ...
My MVC method gets the last write date and appends on the file url:
public static string GetContent(this UrlHelper url, string link)
{
link = link.ToLower();
// last write date ticks to hex
var cacheBreaker = Convert.ToString(File.GetLastWriteTimeUtc(url.RequestContext.HttpContext.Request.MapPath(link)).Ticks, 16);
// static folder is in the website folders, but instead of
// www.domain.com/static/default.css I convert to
// static.domain.com/default.css
if (link.StartsWith("~/static", StringComparison.InvariantCultureIgnoreCase))
{
var host = url.RequestContext.HttpContext.Request.Url.Host;
host = String.Format("static.{0}", host.Substring(host.IndexOf('.') + 1));
link = String.Format("http://{0}/{1}", host, link.Substring(9));
// returns the file URL in static domain
return String.Format("{0}?v={1}", link, cacheBreaker);
}
// returns file url in normal domain
return String.Format("{0}?v={1}", url.Content(link), cacheBreaker);
}
And to use it (MVC3 Razor):
<link href="@Url.GetContent("~/static/default.css")" rel="stylesheet" type="text/css" />
If you are using another kind of application you can do the same, make a method that to append HtmlLink on the page.
If you don't write cookies from domain, the domain will be cookie-less.
When the domain is set to host only resource content like scripts, images, etc., they are requested by plain HTTP-GET requests from browsers. These contents should be served as-is. This will make your domain cookieless. This cannot be done by web-server configuration. Http is completely state-less and web-servers have no idea about the cookies at all. Cookies are written or sent to clients via server-side scripts. The best you can do is disable asp.net, classic-asp or php script capabilities on the IIS application.
The way we do it is.
We have a sub-domain setup to serve cookie-less resources. So we host all our images and scripts on the sub-domain. and from the primary application we just point the resource by it's url. We make sure sub-domain remains cookie-free by not serving any dynamic script on that domain or by creating any asp.net or php sessions.
http://cf.mydomain.com/resources/images/*.images
http://cf.mydomain.com/resources/scripts/*.scripts
http://cf.mydomain.com/resources/styles/*.styles
from primary domain we just refer a resource as following.
<img src="http://cf.mydomain.com/resources/images/logo.png" />
Serving resources from Cookie-less domains is great technique if you have more than 5 of combined images/styleshees/javascript then its benefit is noticeable and is gain even with that extra DNS lookup. Also its very easy to implement :). There's how you can easily set it in web.config[system.web] and have completely cookieless subdomain (unless its cookie-fested by Google Analytics but thats easily curable as well) :)
<!-- anonymousIdentification configuration:
enabled="[true|false]" Feature is enabled?
cookieName=".ASPXANONYMOUS" Cookie Name
cookieTimeout="100000" Cookie Timeout in minutes
cookiePath="/" Cookie Path
cookieRequireSSL="[true|false]" Set Secure bit in Cookie
cookieSlidingExpiration="[true|false]" Reissue expiring cookies?
cookieProtection="[None|Validation|Encryption|All]" How to protect cookies from being read/tampered
domain="[domain]" Enables output of the "domain" cookie attribute set to the specified value
-->
To give you example
<anonymousIdentification enabled="true" cookieName=".ASPXANONYMOUS" cookieTimeout="100000" cookiePath="/" cookieRequireSSL="false" cookieSlidingExpiration="true" cookieProtection="None" domain="www.domain." />
This will set .ASPXANONYMOUS cookie only on www.domain.anyTLD but not myStatic.domain.anyTLD ... no need to create new pools and stuff :).
If you aren't using that cookie, in any way, you could just disable session state in IIS 6: http://support.microsoft.com/kb/244465
In IIS, go to the Home Directory tab, then click the "Configuration" button.
Next go to the Options tab and un-check "Enable session state". The cookie will go away, and you can leave your files where they are with no need for an extra domain or sub-doamin.
Plus, by using additional domains, you increase dns lookups, which partially defeats the intent of the overall optimization.