Uncategorized

ASP.NET 2.0 compiler slowness

 


Here is an interesting problem I worked on a couple of weeks ago for a customer who raised a call with Technical Support: they had an ASP.NET 2.0 application written with Visual Studio 2005, and while working on it they found that when changing a code file contained in App_Code folder and then building the site from the Visual Studio menu command, this took up to 7 minutes to complete… and if they then run a page pressing SHIFT+F5 it took about 25 seconds to compile and display the page. If they just modified the HTML layout of the pages everything worked fine; moreover, it’s interesting to note that if they simply modified and saves their files without building the solution in Visual Studio, but just browsed the page (thus relying on ASP.NET to compile on the fly their code) again everything worked as expected. This seems quite clearly a problem with Visual Studio.


It turned out that this project was originally build with Visual Studio 2003 and ASP.NET 1.1, and they decided to upgrade it to ASP.NET 2.0; they used the upgrade wizard provided by Visual Studio 2005, which will turn on batch compilation (<compilation batch=”true” /> in web.config) when it will detect circular references in the project.


When batch compilation is disabled, ASP.NET will create a separate assembly for each code behind file; in this case the solution had about 3000 “code” files, which would have generated 3000 separate assemblies when compiling and executing the application, each of them individually compiled (with csc.exe or vbc.exe), and as you can imagine this will affect performance. However, we do recommend to set this flag to false immediately after running the wizard in order to catch and fix possible broken assembly references; after these conditions are fixed, you should set batch=”true” (or remove the batch tag) again.


By the way, if you set batch=”true” the compilation model does the building based on each directory, which means it builds one assembly for each directory (if pages’ languages are different we build separate ones). If you request the page through IIS outside Visual Studio, the runtime only builds the directory where the requested page is located. If you build the web inside Visual Studio we build all the directories, and again this is why it takes longer.

Changing the content in “App_Code” folder will cause clean build throughout all the web site. You can think of the “App_Code” folder is a project, and each web page is a separate project which all reference to the “App_Code” project; if the “App_Code” is updated, we will have to rebuild all the web page projects. Incremental build might make sense within each project, but not cross projects scenarios; this is a change from the Visual Studio 2003 project system and I have to say it is hard for users to realize…

In this situation I recommend you turn off “Build web”: you can do this by opening the “Property Pages” dialog, switching to “Build” tab and setting the “Before running startup page” to “No Build”. Now you will have the delay only caused by runtime (~45 seconds). You can manually invoke “Build web” anytime later if you want to validate those pages.

But now compilation of App_Code alone happens only when I hit F5 (to debug)… If you choose “Build”, it still compiles App_Code *and* web pages. How could you then build only App_Code, without hitting F5?

The feature of building “App_Code” only was cut from Visual Studio 2005; the closest approach is to build one aspx page (“Build”->”Build page”), which will first build “App_Code”, and then that specific page, while no other pages will be built.

Cheers
Carlo

Leave a Reply

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.