This - my first official blog entry- will be about how to store your images and media using Kentico for maximum site responsiveness and perceived performance.
There is quite a bit of information out there currently about how to tweak and tune Kentico performance in addition to tips on code sites so that they perform well. I recommend you read the blog by Kentico on the subject, as well as the very through blog by Brian Soltis. They are excellent sources of information about general Kentico performance.
A perfect example of Kentico's flexibility is in the way that Kentico handles images and media files. You could for instance:
- Store the files in the database as part of the CMS
- Store the files on the filesystem as part of the codebase
- Store the files in media libraries which offer a unique hybrid approach
- Store the files in the database and have them cached and loaded from disk
- Store the files in the database and have the browser redirected the the disk version
In addition there are other options that affect the way images are loaded / cached both on the server and the client side for you to consider:
- Kentico standard caching
- Full client caching
Lastly you can have the system check to see if the current user has permissions for the file and/or the file is published before retrieving it.
Each and every option above affects how long it takes an image to be sent to the client browser, and thus how performant your site feels to and end user. I set out to compare these methods side by side to determine which approach offers the best performance. It is worth noting that each approach has positives and negatives that go beyond just performance and it is important to understand these before choosing the approach that works best for you.
Here are the approaches that I tested and the positives and negatives of these approaches.
1) Store the files in the Kentico CMS tree
This method provides the highest level of flexibility for content editors (let's face it images are frequently part of the content of a site). This also allows for the easiest transition between multiple cultures since the files would be considered a document and thus have a different(or the same) version for each culture. The downsides to this approach are that Kentico doesn't like to can't have two files with the same name in the same folder. This defeats a popular method of back-browser compatibility where you would store a newer transparent PNG for modern browsers and a transparent GIF for IE6. Some of the options you can use for performance tuning on this approach are:
This setting tells Kentico not to re-retrieve the information from the database unless it has changed since the last time it was retrieved. If
<add key="CMSFullClientCache" value="true"/>
is added to the web.config then Kentico will also send an expires header to the client browser telling it not to re-request the image until the cache is expired. In my opinion there is a flaw in this implementation that I will cover in my next blog. If client caching is not enabled then Kentico will send a "304" response so that at least the browser doesn't have to re-download the file.
This is configured under the properties for the file (or preferably the entire folder of files) in the "General" section near the bottom as show in this screen shot
This setting tells .NET not to re-run the code required to retrieve this image once it has been retrieved the first time, unless the cache is invalidated. Kentico will invalidate the cache once a file has been changed so there is little danger here unless you are not using the Kentico API to update your files in the CMS.
Store Files on Filesystem
This is configured in Site Manager in the Files section as shown below
This setting will tell Kentico to store the files on the disk which should offer slightly better performance in some cases vs files stored on a database. In my experience this setting does not work well in a multi-cultural website where you are using the exact same image in multiple cultures with different data. In this case the first culture that is accessed will write the image to the disk and all other cultures will access this version rather than the correct version. I will caveat this by saying that I have not tested this behavior since Kentico version 4 and it could have well been corrected. Your mileage in this case may vary.
Check if files are published / files permissions
This setting is also configured in the files setting section of Site Manager as shown
This setting will cause Kentico to check every time a file is accessed to determine if that file is currently published, and that the current user has permissions to it respectively. This can be important for some implementations so make sure you understand how your files are being used before you turn off this setting. This is a global setting for the whole site, it would be really nice to see this setting on a folder by folder, or file by file basis.
Redirect files to disk
Once again this setting is configured in the Files section of Site Manager
This setting will cause Kentico to re-direct the browser to the disk based version of the file rather than it's own version. Kentico will re-write these files as they change so again little danger here if your using the Kentico API for everything (as you should be).
2) Media Libraries
This approach allows Kentico to keep meta-data about a file in the CMS system but the file is always stored on the file system. Since the meta-data is in the CMS system these files can be accessed, updated, and linked to using common CMS controls. How to setup a media library is beyond the scope of this blog, but there is lots of good documentation about it on the Kentico documentation website. The downside to using this approach is that media library files are not versioned, they are not culture aware, and I have had problems with using content staging for large files. If you are developing a multi-cultural site then you will need to come up with an effective way of handling using different version of the same file in different cultures. Using different files in each culture, or the exact same files. is not an issue.
Since the files for the media library are stored on the file system there are few options for performance tuning in the media library as the files come directly from IIS, any performance tuning would be done in IIS.
There is one setting to be aware of when using media libraries, "Use permanent URLs" in the "Media libraries" settings section of Site Manager will cause files referenced in a media library to use a "permanent URL". This permanent URL goes through the CMS system; in this case you effectively end up with the same thing as storing files in the CMS tree, but having them stored on disk.
3) Store the files in the codebase
Note: Any time your deal with files directly on the file system that are being served by IIS, regardless if this is through a media library or through the codebase directly you are limited by the MIME types that IIS is aware of. In IIS6+ the web server will throw a 404 for any file extension that it does not understand, this can cause problems in shared hosting environments, or environments where configuring the IIS MIME types is not possible.
In order to test the performance of these various approaches and various settings I used Firefox 3.6 with Firebug installed. I cleared my cache between each test run and recorded the results from the Firebug Net panel.
To simulate a "cold" Kentico cache, the Kentico cache was cleared and the application was restarted using the System section of Administration in Site Manager. The image that was downloaded was 4.1Kb and is below:
The image was placed in the Kentico CMS tree as well as in the codebase and I created a page where I could review the results side by side to make sure that I was not seeing variance based on network conditions. The page was served by Kentico in order to simulate a real world environment. I performed three test runs per approach I was testing and recorded the results in an Excel file; I then averaged the results to create the final table.
Here are the results, all numbers are times in milliseconds and "Cold" means without Kentico having cached the file yet. The important column here is "Total" which indicates the total amount of time before the browser can "use" the file.
|Type of Load||Waiting||Receiving||Total|
|Static File (IIS / Media Library)||66||34||100|
|Kentico Cold w/o Permissions Check||303||36||339|
|Kentico Cached w/o Permissions Check||127||44||170|
|Kentico Cold (No Cache) Store on File System||364||37||400|
|Kentico Cached Store on File System||137||36||174|
|Kentico Cold (No Cache) w/o Perms Check Store on FS||364||35||399|
|Kentico Cached w/o Permissions Check Store on File System||98||38||136|
|Kentico Cold (No Cache) Store on File System w/Redirect||537||34||571|
|Kentico Cached Store on File System w/Redirect||194||35||228|
|Kentico Cold (No Cache) w/o Perm Store on FS w/Redirect||334||54||388|
|Kentico Cached w/o Permissions Check Store FS w/Redirect||211||35||246|
Here is the XLS file with the RAW results: Download Kentico File Load Times
Using the "Redirect files to disk" option actually causes the browser to make 2 requests. The first is the request to the original file in the CMS system for which Kentico returns a "301" redirect. The second is the request the the file on the disk, this actually causes a rather unique "double latency" effect and could have a profound impact on the number of requests a browser has to make to load the files for a page. This behavior is show below:
Serving files off the file system, or through media libraries offers the best performance; however it restricts some of the flexibility you get using files in the CMS tree. If you need to store files in the CMS tree then you should disable the permission and published checks if at all possible. If you need to use either of these features in your implementation then I recommend only storing the files where you need to use features in the CMS tree and using the file system or media libraries for the bulk of the files. As always there is no "one size fits all" solution to how to store files in Kentico, however these findings should provide you with the information you need to make educated decisions about your approach and deliver the highest quality experience possible.