16 08 2016
ASP.NET MVC: Precompiling views
This blog post is about how to really precompile ASP.NET MVC views. It destroys the myth about MvcBuildViews as precompilation tool and shows you how to configure precompiling. It also stops on some internals of precompiling and explains what are the options and limitations with it. There is also real-life example for Azure where precompiling of views may avoid some serious headaches that one may face otherwise.
What is MvcBuildViews?
MvcBuildViews is often mistakenly considered as something that when activated results in precompiled views. It doesn’t, actually. It is just a thing to include views to build process but it doesn’t compile these to project binaries folder. MvcBuildViews builds views temporarily and gives build results back to building process. If there were errors then build fails and errors are shown in Visual Studio errors window.
You can find out more about MvcBuildViews from Jim Lamb blog post Turn on Compile-time View Checking for ASP.NET MVC Projects in TFS Build 2010.
How to precompile views?
As precompiling is kind of expensive and time consuming process you really want to do it when publishing application to test or live environment. Simplest way to do it is using web site publishing. Publishing configuration has settings page where you can turn on compiling of views.
If you publish your web application then you will discover that only global.asax has something precompiled for it. But there is nothing for views.
By default it is expected that there can be updates to views and it is possible only if views are not compiled to assembly. As soon as there is assembly for views modifications to view files are not automatically reflected in application output.
Let’s open advanced settings and turn off updates to views. As ASP.NET compiler creates separate assembly for every view it’s possible we get big number of very small assemblies if there are many views. It’s possible to specify the name of assembly where all those small view assemblies are merged.
Now you are good to go with precompiled views when publishing your application.
NB! Although it may seem like good idea to have precompiled views available also on dev boxes, I suggest you to abandon this idea. Precompiling takes time more than developers want to wait and it slows down their progress as after every build they must wait until precompiling is done.
NB! If you precompile views then views are not updatable anymore. It means that if you change view file on server you don’t see any changes in output. This is because precompiled views are called from DLL-file. You have to publish your application again if you made changes to views.
Precompiled views after publishing
After publishing precompiled views can be found from bin folder of web application. In my case there is AppCode.dll file that contains code for all precompiled views. But besides this there are also files with .compiled extension. These files tell ASP.NET where is output of given view.
In my case there’s file _smsdialog.cshtml.49841770.compiled in bin folder. Here is the content of this file.
<preserve resultType=“2“ virtualPath=“/Views/Dialogs/_SmsDialog.cshtml“
hash=“ffffffffda035ab6“ filehash=“166a10c1bc59“ flags=“110000“
<filedep name=“/Views/Dialogs/_SmsDialog.cshtml“ />
It defines file dependency and specifies where is the code for this view (assembly and type attributes of preserve node).
If I open AppCode.dll with decompiler I can see the source code of precompiled view.
As precompiling is done by ASP.NET command-line utilities you can also use precompiling on your build server.
Precompiled views on Azure
I worked on application that has some complex views. Compiling this views on runtime is slow even on dev box wit fast hard disc. It turned out to be times slower on Azure compute instance where web application is hosted. I investigated virtual machine that runs compute role and made the following discoveries:
- regular discs on Azure are very slow,
- compared to similar discs available they beat them only with one thing: the energy consumption,
- SSD-s are way more expensive on Azure that regular discs,
- the less disc I/O application generated the faster it is.
This is ideal case for precompiling the views. It’s not possible to avoid those .compiled files but getting all code for views to one assembly makes application startup faster because there’s only one library to load. With precompiled views your application works way faster after deployment because ASP.NET doesn’t have to build and compile views to compute role hard disc.
The main take-away of this post is: MvcBuildViews is here to make building of views as part of web application building process. It doesn’t generate any output to binaries folder. Views are precompiled during publishing process and precompiling happens only if views are not expected to be modified. It is possible to configure how precompilation is done. This way it is possible to merge binaries of precompiled views to one assembly. This way it is possible to shorten the time it takes for application to start. As it turns out then precompiled views are good choice for web applications that run on Azure as it avoids some really slow disc I/O and web application gets highly responsive way faster than otherwise.