Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MvcBuildViews in MS2015 takes a long time

We are converting a solution to use the new Roslyn compiler. When I build it via teamCity in release mode, the MVCBuildViews step still uses aspnet_compiler.exe and it takes about 15 minutes to precompile views. The same process used to take 3 minutes using the previous version of aspnet_compiler.exe on .NET 4.5

This is the command that takes a while:

C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_compiler.exe -v temp -p E:\path\to\web\project\Directory

I have tried tweaking the MSBuild parameters but nothing changed. is this a known issue, are there any work around, Do I need to pre-compile the view with Roslyn ? what is the drawback for turning turn off the MVCBuildViews step if it is an option ( I believe our choice to pre-compile on release is what causes this step to run).

like image 678
delloPiro Avatar asked Feb 11 '16 02:02

delloPiro


1 Answers

We've hit the same issue at Stack Overflow, that's why we created StackExchange.Precompilation. You can read about it in our announcement blog post, but here are some gory technical details, as we, naturally, investigated why aspnet_compiler.exe was so slow, before writing our own replacement for it.

aspnet_compiler.exe has been around long before asp.net-mvc and razor, and of course, it supported stuff like batch compilation via <compilation batch="true" />. In order for a view to be compiled though, the CSHTML template has to be transformed into C# (CodeDOM), first. Unfortunately, this isn't compilation as such, so batch="true" doesn't apply to it. (in-)Effectively, views are processed in sequence, one view at a time. And any roslyn features you add on top of it only slow it down, since there has to be a CodeDOM -> roslyn conversion at some point.

Here's a nice stack trace, of what's going on before a batch compilation in aspnet_compiler.exe takes place.

aspnet_compiler.exe foreach loop

Notice this AddBuildProvider call (which calls GenerateCode) is already inside two foreach loops. I guess the batch="true" options was only ever effective at speeding up the compilation of App_Code in Website Projects...

This is what happened to our build times afterwards:

enter image description here

I wouldn't recommend disabling the precompilation to anybody running an ASP.NET MVC app in production.

  • The most obvious argument for it is, that it verifies you view code. Otherwise, you trade compile-time errors on the build server for run-time errors, in production.
  • The other argument for it is performance. Your views have to be compiled at some point, and if it doesn't happen at compile-time, the first few users that hit your site have to wait, again, in production.
like image 56
m0sa Avatar answered Oct 21 '22 06:10

m0sa