Recently we’ve observed that it takes too long for our ASP.NET MVC web application to be up and running after a build. It didn’t take long to find out that the cause of the problem was the recompilation of Razor views.
Most of people on the Internet are concerned with the downtime of the production environments after rolling out a new version, and the pre-compilation of views is able to solve it. However, in our case it’s the development process that is being hampered, so naturally pre-compilation gains nothing. Other commonly found advices like turning off unused view engines haven’t had significant results as well.
But why does it take so long to compile a bunch of views? It turns out, the complexity of views affect the total time only to a small extent, but what really matters is how much view folders are there, specifically how much views located outside of the current folder a given view uses.
I’ve created a small application based on the default ASP.NET MVC project with several partials added to the Home page:
Let’s see what Mini Profiler can tell us about the rendering times of the Index page right after a build:
Results suggest that the first partial is so complex that it takes a lot of time to render it; however, the view consists only of a small text string, and swapping the content with other partials does not make any difference. Moreover, partials 2 and 3 take practically no time to render, and so does the partial located in the same folder as the view.
Further experimentation confirms that the rendering of a partial itself takes a negligible amount of time – however, the first time framework encounters a new folder, it stumbles quite noticeably , obviously performing some activity.
Why is it so? Let’s run the trusty DotTrace:
Let’s look at CompileWebFile method in Microsoft reference sources:
So it seems that whenever the view compiler sees a web file, it tries to compile the whole directory (but not more!). What happens next is that we run the compiler and wait until it’s done:
Starting a process is an expensive task, of course, so that explains why we were observing a noticeable delay.
The conclusion to be made is that a dashboard style home pages doesn’t play well with ASP.NET MVC if their component views are located in different folders. I do not know a solution to this problem, because the build strategy is buried well inside the MVC internals, so for now the advice would be to keep everything you reference in the same folder as much as possible.