Overview
The support files used in a web site, especially javascript and css and images, change quite rarely. Long duration cache headers give a major performance benefit. DNN's standard tooling automatically provides cache busting parameters. Cache busters allow site developers freedom to change scripts, css and images. Those changes can be immediately propagated to the site users. Download a powershall script to automate setting up cache headers.
Details
There are only two things you need to know about caching. "Don’t cache HTML. Cache everything else forever." Quoted from this article. You should read it now. Go on. I'll wait!
The quoted article teaches that controlling cached items needs a sure fire way of using a different url when an item changes. DNN gives a lot of help in doing that. Install Fiddler (other great tools exist) to see the url's DNN generates for the different parts of a page. Fiddler monitors all the http traffic from your machine. A request for this site's home page might look like this...
The basic page is roughly 21K bytes. Then there is near on a megabyte of javascript and CSS required to support the page. The megabyte of javascript and CSS never (OK rarely) changes. The web site and the browser already recognize that. The browser will drop all of the javascript and the CSS into its local cache, just in case. On a subsequent page request the browser recognizes that there is a copy in the local cache and makes a conditional request for the files. Essentially it says "I already have a version with 'this date'. Is that the same version as you would send me?" If it is the version that the server would send, the server returns a 304 response and does not send the full file content. It still requires time to round trip the request to the server but saves the time, and bandwidth, of the full data. In Fiddler it looks like this.
When a response comes back with a caching header, it promises the browser that the data at that url will remain valid for the period specified in the header. For example, in the first image, /Portals/_default/default.css?cdv=73 mentions max-age=31104000 specifying a period of 360 days (in seconds). Once the browser receives that promise, when *any* page on the site requests the cached url the browser does not contact the server at all. The file is used directly from the cache. This is a valuable saving, default.css is used on every page of a DNN site.
Note the urls that end in cdv=73. These are generated by DNN. Some of them come from the basic process of creating a DNN page. Some come from skin objects such as DnnCssInclude and DnnJsInclude. The parameter on the url is never used by the Web server. It is purely there to bypass any locally cached browser content with a different parameter value. Such a parameter is often known as a 'Cache Buster'. The cdv parameters are supplied by DNN. They are controlled from Host Settings on the Advanced Settings Tab
Note that the 73 reported there is the same as the cdv=73 parameter. DNN defines a few circumstances that automatically increment the number. If the automated features don't meet our needs there is a button to increment it manually. After that increment no client browser will have a copy of the new url and browsers will have to request a full fresh copy. This technique allows site management to get the benefits of caching; ensure that clients see up to date information; and have a largely fully automated solution.
From this we can infer that it should be safe to cache any resource that carries a cdv=* parameter. We can also infer that it's highly risky to cache a resource that does not carry a cache busting parameter.
How to supply cache header information for a file
The easiest way is with a small web.config file in the folder. The location may specify a file – the cache headers are applied to that file only. The location may specify ‘.’ – the cache headers are applied to any file in that folder. Such a web.config file looks like this...
PowerShell makes it easy
I wrote a PowerShell script to make it easy to generate and add the relevant web.config files. You will need direct access to a command shell on the web server to use it. Download it from GitHub (https://github.com/RichardHowells/Dnn.Caching) to a folder on the server. Open a command prompt and navigate to the folder containing the script. Type the command
powershell –f SetupCachingForDNNSite –webSiteRootFolder "Full path to the root folder of your web site"
At the time of writing this will add web.config files to cache:
- default.css
- all files in Resources\Libraries
- all files in js
- all files in Resources\Shared\Scripts
- all files in Resources\Shared\Components
It will then iterate over every Portal folder in the Portals folder (it skips the *-System folders)
- it will add a web config file to cache portal.css
- it will create a CachedFiles folder if there is not one there already; and add a web.config to cache every file in that folder.
The intention is that you will manually move your logo image and favicon icon into that folder, changing the site settings to pick them up from that folder. They will then be automatically cached too.
Results
After clearing the browser cache every byte of data needs to be retrieved from the server. This is the worst case and is often referred to as 'cold cache'. When some, or all, of the data is already in the cache this state is referred to as 'warm cache'. The process of loading data into the cache is referred to as 'warming the cache'.
To retrieve this site's home page:
Cache State |
Requests |
Approx total bytes |
Elapsed time |
Cold |
43 |
1MB |
4 seconds |
Warm |
3 |
27KB |
Under 1 second |
Clearly the warm cache results are massively better although the cold cache is the worst possible case and real-life performance would be better.
Summary - TL;DR;
The support files used in a web site, especially javascript and css and images, change quite rarely. Long duration cache headers give a major performance benefit. DNN's standard tooling automatically provides cache busting parameters. Cache busters allow site developers freedom to change scripts, css and images. Those changes can be immediately propagated to the site users. Download a powershall script to automate setting up cache headers.