Hi Beth,
I did some experimenting with pre-compiling over the weekend.
Really Web Application projects like mojoPortal are pre-compiled already in the sense that all the .cs files are pre-compiled into dlls in the /bin folder, but all the files like .aspx, .ascx, .asax, .resx are not pre-compiled so those files normally need to be compiled by the ASP.NET compiler. Those files can be thought of as partial classes just like .designer.cs files are partial classes to a page or control, the .aspx or .ascx etc is compiled also as a partial class corresponding to the code behind .cs file that is already compiled in the bin.
So taking the deployment package and opening it as a web site (rather than a Web App Project which it was before deployment), it is possible to further pre-compile the .ascx, .aspx, .resx etc files by publishing it again while treating it as a web site project rather than a web app project.
However in my tests I discovered that one problem with pre-compiled sites is that VirtualPathProviders do not work, even the documentation on VirtualPathProviders here mentions that they do not work in pre-compiled apps. Since we use a VirtualPathProvider to map the theme.skin files from the skin folders, the result is errors that the theme compiler could not find the theme. From further googling I found a workaround that does work, but it uses reflection and therefore can only work in Full Trust hosting because reflection is not allowed in Medium Trust. I'll list the steps here in case you want to try it for your deployment.
1. Produce a build the normal way and deploy it to a local folder
2. Move the Data folder to another location because it doesn't work if the skins are are included, so remove it from the initial deployment folder.
3. Open the initiall deployment folder in VS as a Web Site
4. This part is the workaround, right click the web site in VS and choose Add ASP.NET Folder, and choose App_Code. Add a new item to the App_Code folder, chooose class, and name it AppInitVPP.cs, and paste in the following code:
using System.Web.Hosting;
using System.Reflection;
using System.Collections.Specialized;
using mojoPortal.Web;
public static class AppStart
{
public static void AppInitialize()
{
// we create a new instance of our own VirtualPathProvider.
mojoVirtualPathProvider providerInstance = new mojoVirtualPathProvider();
// any settings about your VirtualPathProvider may go here.
// we get the current instance of HostingEnvironment class. We can't create a new one
// because it is not allowed to do so. An AppDomain can only have one HostingEnvironment
// instance.
HostingEnvironment hostingEnvironmentInstance=(HostingEnvironment)typeof(HostingEnvironment).InvokeMember("_theHostingEnvironment", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.GetField, null, null, null);
if (hostingEnvironmentInstance== null)
return;
// we get the MethodInfo for RegisterVirtualPathProviderInternal method which is internal
// and also static.
MethodInfo mi = typeof(HostingEnvironment).GetMethod("RegisterVirtualPathProviderInternal", BindingFlags.NonPublic | BindingFlags.Static);
if (mi == null)
return;
// finally we invoke RegisterVirtualPathProviderInternal method with one argument which
// is the instance of our own VirtualPathProvider.
mi.Invoke(hostingEnvironmentInstance, new object[] { (VirtualPathProvider)providerInstance });
}
}
5. Right click the web site and choose Publish Web Site. Leave the box checked that says "Allow this precompiled site to be updateable". Choose another folder to deploy to and choose ok. (Note that this means the .aspx and .ascx files are not really going to be pre-compiled, but .resx files will and it still should load faster on startup. If you uncheck the box, then all of the deployed .aspx and .ascx files are empty if you open them in a text editor, but in my testing it did not work correctly doing that. It seemed like it was not laoding the right master page and the column layout was not working, but if you leave it updateable it works.
6. Restore the /Data folder to the new deployment folder and now the package is ready for actual deployment.
In Full Trust it works for me but in Medium Trust it throws a security exception due to the use of reflection.
All in all, I'm pretty sure that the slower startup time is caused by the increased number of .resx files as we've added more and more translations. So removing languages that you don't need from /App_GlobalResources is probably going to be almost as helpful as trying this process of pre-compiling, and less complicated, but it is an option if removing the extra .resx files doesn't improve things enough. You could write a script to automate the removal of non-English .resx files if English is the only language you need. Note also that adding or removing files from the /App_GlobalResources folder causes the app to restart the same as touching a web.config file.
Hope that helps,
Joe