Starting CMS 6 sites faster after build
In this blog post I will show you how you can half the time it takes an EPiServer CMS 6 site to warm up after a build. If you rebuild as often as I do during a workday, this post will saves you a few hours over the next year. Warning: This will seriously cut into your coffee breaks
New blog post updated for EPiServer CMS 6 R2
I have written an updated version of this blog post here. I would recommend reading it instead.
Why…. is…. it… so…. slow….
Starting an EPiServer CMS site after a build has always been a slow affair. Even on my brand new Core i7/8GB RAM/SSD laptop it takes EPiServer CMS 14 seconds to warm up after a build. The good news is that you can half this time by following these tips!
But before I show you how, lets have a look at the improvement I got on my EPiServer CMS 6 Alloy demo site:
The warm up time for my demo site went from 14 seconds to 7 seconds after adding these tips!
Step 1: Make EPiServer start faster
The first thing we are going to do is to is something called “Preventing initializing of known assemblies”. It sounds hard, but it is very simple. We just need to modify a config file.
I learned about this trick during EPiServer Techforum in Oslo, but I know it has been written about before online. When EPiServer CMS 6 is started it scans all the assemblies in the bin folder for stuff to initialize. This takes a long time, and by telling EPiServer what assemblies does not need scanning we can cut warm up time in almost half.
What to do:
Open the EPiServerFramework.config file found in the root of your project.
It will look something like this:
<episerver.framework>
<scanAssembly forceBinFolderScan="true" />
<siteHostMapping>
<siteHosts siteId="???">
<clear />
<add name="*" />
<add name="??????" />
</siteHosts>
</siteHostMapping>
<automaticSiteMapping>
<add key="????" siteId="???" />
</automaticSiteMapping>
</episerver.framework>
We need to tell EPiServer what assemblies not to scan, so modify the <scanAssembly> section it so it looks like this:
<episerver.framework>
<scanAssembly forceBinFolderScan="true">
<add assembly="*" />
<remove assembly="DocumentFormat.OpenXml" />
<remove assembly="ElektroPost.Licensing" />
<remove assembly="EPiServer.BaseLibrary" />
<remove assembly="EPiServer.Blog" />
<remove assembly="EPiServer.Configuration" />
<remove assembly="EPiServer.Data.Cache" />
<remove assembly="EPiServer.Demo.ExcelPageProvider" />
<remove assembly="EPiServer.Demo.FileManager" />
<remove assembly="EPiServer.ImageLibrary" />
<remove assembly="EPiServer.Implementation" />
<remove assembly="EPiServer.Legacy4" />
<remove assembly="EPiServer.Licensing" />
<remove assembly="EPiServer.LinkAnalyzer" />
<remove assembly="EPiServer.Log.Analyzers" />
<remove assembly="EPiServer.Log.Core" />
<remove assembly="EPiServer.Lucene" />
<remove assembly="EPiServer.Scheduler" />
<remove assembly="EPiServer.Scheduler.WKTL" />
<remove assembly="EPiServer.Templates.Demo" />
<remove assembly="EPiServer.Templates.Public" />
<remove assembly="EPiServer.Web.WebControls" />
<remove assembly="EPiServer.WebDav" />
<remove assembly="EPiServer.WebParts" />
<remove assembly="EPiServer.WorkflowFoundation" />
<remove assembly="EPiServer.XForms" />
<remove assembly="EPiServer.XmlRpc" />
<remove assembly="log4net" />
<remove assembly="Microsoft.Web.Services3" />
<remove assembly="System.ComponentModel.Composition" />
<remove assembly="System.Web.DataVisualization" />
<remove assembly="System.Web.Mvc" />
</scanAssembly>
Leave the rest as is....
For advanced developers: You can also add your own assemblies here if you know they don’t need initialization. There is a great tool on EPiWiki.se that will scan your bin folder and generate the EPiServerFramework.config for you. (Please note: It will report EPiServer.UI as not need, this is wrong, it needs init)
Step 2: Warm Me Up
Until EPiServer supports Auto-Starting, your site is not going to warm up until you request the first page. So in the second part of this blog post we are going to set up a warm up of the site as part of the build process. This will not actually make your site start faster (it will take just as long no matter how you do it), but it will shave some seconds off as you switch to your browser and reload the page you are working on.
To do this I have written a little console application, WarmMeUp, that take an url as an argument and then asynchronously calls that url. I have included the full source code so you can see how it works.
What to do:
1. Download the WarmMeUp program and unzip it do e.g. c:\WarmMeUp\
2. In Visual Studio right click the solution in Solution Explorer and select properties.
3. Add the following line to the “Post-build event command line” box: c:\WarmMeUp\WarmMeUp.exe http://localhost/
(Make sure to change this to match your location of WarmMeUp.exe and the url you want to warm up).
Now try rebuilding your site and see if it starts quicker
Testing warm up time
To test the warm up time for this blog post I wrote a simple HTML/javascript page. Feel free to run this before and after you make the suggested changes and share the improvements in the comments below.
<html>
<head>
<title>Page timer</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.js" type="text/javascript"></script>
<script type="text/javascript">
var URL2Time = 'http://localhost/';
function Timer()
{
document.getElementById("loadingtime").innerHTML = "Waiting for response...";
var beforeload = (new Date()).getTime();
$.get(URL2Time, function(data) {
var afterload = (new Date()).getTime();
var seconds = (afterload-beforeload)/1000;
document.getElementById("loadingtime").innerHTML = "Your page load took " + seconds + " seconds.<br>(" + URL2Time + ")";
});
}
</script>
</head>
<body>
<input type="button" onclick="Timer()" value="Load url and start timer" />
<p><div id="loadingtime"></div></p>
</body>
</html>
Feedback
I appreciate your feedback on this blog post, especially how much quicker your sites starts after a rebuild when implementing these suggestions. Please comment below or send me a tweet: @ahaneng
Posted by Alexander Haneng
Great and very useful post!
This, of course, also applies to Community, where the end result will be even more appealing!
I concur with the previous speaker!
Nice post Alexander! Regarding step 2. I use the IIS application warm up module:
http://www.iis.net/download/applicationwarmup
Its intended for production use but works well in a dev environment too
I would like to contribute with one small thing that also speed up starting after recompilation:
Add optimizeCompilations="true" to your web.config compilation-tag.
Read more about it here: http://blogs.msdn.com/b/davidebb/archive/2009/04/15/a-new-flag-to-optimize-asp-net-compilation-behavior.aspx
Check out this great tools for better detecting what assemblies don't need scanning:
http://www.david-tec.com/2011/11/Integrating-EPiOptimiser-into-Visual-Studio/
Great article! This helped me alot, but still having performance issues, while starting up my website.
I also added:
to web.config, which cut of some compilationtime as well.
I'm running a EPiServer CMS 6 site, with EPiServer Commerce and EPiserver Community. The startup time is now cut to half, but it still takes about 30 sec, on my i7/8GB/SSD laptop.
Any suggestion? Is there any known issues, while working with EPiServer Commerce and Commity?
Great pointers Alexander! Just remember to refresh the list of assemblies if you do an upgrade as there might be changes to what assemblies that need to be a part of the scan.
I have written an newer blog post about this topic here:
http://world.episerver.com/Blogs/Alexander-Haneng/Dates/2011/12/Starting-CMS-6-R2-sites-faster-after-build/