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.

View building error in Visual Studio

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.

ASP.NET publishing settings

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.

ASP.NET precompile settings

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.


<?xml version=1.0 encoding=utf-8?>
<preserve resultType=2 virtualPath=/Views/Dialogs/_SmsDialog.cshtml 
          hash=ffffffffda035ab6 filehash=166a10c1bc59 flags=110000 
          assembly=AppCode type=ASP._Page_Views_Dialogs__SmsDialog_cshtml>
  <filedeps>
    <filedep name=/Views/Dialogs/_SmsDialog.cshtml />
  </filedeps>
</preserve>

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.

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.

Wrapping up

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.


6 thoughts on “ASP.NET MVC: Precompiling views

  • Mike J says:

    Informative. Dispelled a lot of myths about pre-compilation. Do yiu have any tips for improving the peofdmance of the aspnet_compiler during publishing. In my project this step takes almost 1 hour and it’s not uncommon from what I understand.

  • Gunnar says:

    I suggest you to check you dev box disc performance. Visual Studio and ASP.NET web tools may cause massive disc I/O when building, compiling or generating things. If disc is the bottle neck then switch over to SSD.

  • Ryan Heath says:

    Have you every encounter a failure on Azure with precompiled views?
    It worked on the dev machine but when deployed on the azure server it would not run.
    I had but could not solve it and went back to deployment without precompiled views …

    // Ryan

  • Chad says:

    > As precompiling is done by ASP.NET command-line utilities you can also use precompiling on your build server.

    Do you have examples of those command line utilities?

    When I try your steps I get some failures because the post-compiler does not recognize C# 6 features (specifically string interpolation).

    Thanks for the post, this is something I’ve been wanting to nail down for a long time!

  • Chad says:

    *Update* on the C# 6 syntax not recognized error: I changed my web.config to “Content” Build Action (previously it was None) and in doing so, the web.config file was copied to the `obj\Release\AspnetCompileMerge\Source` directory. Now the C# 6 syntax is recognized.

    It is worth noting that I have the following tag changes from this stackoverflow answer: http://stackoverflow.com/questions/31548699/how-to-use-c-sharp-6-with-web-site-project-type#answer-31548773

  • Gunnar says:

    Ryan, I have used precompiled views only on compute instances as most of my Azure customers use these due to need for more control over VM-s where applications run. With compute instances we have had no problems this far.

Leave a Reply

Your email address will not be published. Required fields are marked *