Tips to optimize design-time build performance for Web Sites in Visual Studio 2005

Published Tuesday, December 6, 2005 1:03 AM
There have been a number of posts with tips to improve build performance within Visual Studio 2005.  I've consolidate these posts and other tips into a single post of techniques for common problems.

Do not disable batch compilation
Make sure web.config does not have <compilation batch="false" />
The default is “true” so unless it’s explicitly set to “false” you’re ok.

Some post have recommended disabling batch compilation to address a migration issue with circular references.  Unfortunately this dramatically impacts build performance.  You're much better off addressing the circular references than to disabling batch compilation.

Leverage Server-side Compilation
Visual Studio 2005 is leveraging ASP.Net 2.0 server-side compilation.  The IDE is primarily validating that the site will compile.  For most edit/run iterations it's not really necessary to validate/build the entire site on every F5 or solution build.

Change Build options for the web site project:  (Property pages <shift>F4 -> Build)
    “Start Action (F5)” should be either "build page" or "no build".  -  Improves F5 performance
    “Build Solution Action” uncheck “Build Web as part of solution.”  -  Makes <ctrl><shift>b very fast.

While this does improve build performance because ASP.Net is only compiling the files needed for the request on F5, it doesn't help the developer identify all the compilation issues within the IDE before running.  There are a couple of techniques you an use to help with this.
  1. Move App_Code files into a separate class library project and reference it form the web site project.  This will improve build performance and provide all compilation errors for these class files within the IDE.
  2. Add a Web Deployment Project to the solution.  Configure the Web Deployment project so that it only builds for the release configuration.  This will allow you to completely validate the site before deployment without compromising the performance of the edit/run iterations under the debug configuration.

Move App_Code files into a separate class library project
I'm repeating this tip because even if you don't change the default build options you can improve build performance by moving the files from App_Code into a separate class library project.

Check for conflicting dependencies
If you do have conflicting dependencies, the web site project will do a full clean rebuild on every build even if only a page changes.  The problem is when you add a file based references that have a common dependency but to different versions of that dependency.   A file based references have a .dll.refresh file in the bin folder.  The .refresh file has the path to the original assembly.  These paths are checked on every build.

In this example we have two assemblies, A.dll and B.dll both dependent on Foo.dll.

    A.dll -> dependent on Foo.dll
    B.dll -> dependent on Foo.dll

When A.dll is refreshed the project system will discover the dependency on Foo.dll and copy it into bin. Likewise when B.dll is refreshed Foo.dll will be copied if different than the one already in bin. The problem is that when a class library is built by a class library project in VS it caches the dependencies. So as you can see here Class Libraries A and B both have a private copy of Foo.

ClassLibraryA
    A\bin\debug\A.dll
    A\bin\debug\Foo.dll

ClassLibraryB
    B\bin\debug\B.dll
    B\bin\debug\Foo.dll

ClassLibraryFoo
    Foo\bin\debug\Foo.dll

If ClassLibraryFoo is updated and only ClassLibraryB is recompiled then ClassLibraryB has a updated copy for Foo.dll but ClassLibraryA does not. When the web project is built, the refresh of A is copying in it's copy of Foo and the refresh of B is copying in it's copy. Each time Foo is copied because it's different than the one already in bin.

Because the bin is changing with every VS build the ASP.Net compilation cache is invalidated forcing a full build.  Thus every build is a full build.

To fix this problem do one of the following:

  1. Add class libraries A,B and Foo to the same solution as the web site and replace the file base references with project references.
  2. Always build all consumers of a dependency when the dependency changes.
  3. Remove the .refresh files and manually update as needed.

Turn off AutoToolboxPopulate in the Windows Forms Designer options. 
Some user have reported a hang during build.  This was resolve by turning off AutoToolboxPopulate.
http://forums.asp.net/1108115/ShowPost.aspx

    Tools/Options/Windows Forms Designer/General/AutoToolboxPopulate = False

Disable validation for HTML editing
By default the HTML/ASPX editor performs html validation in the background while the file is open.  This does not normally impact performance unless there are numerous error to report.  So if you're already compliant, turning it off won't save you much but if you do have errors and don’t' need to fix them, turning if off can make a difference. 
http://msdn2.microsoft.com/en-us/library/0byxkfet.aspx


You'll be surprised at the performance improvement these changes will make for the edit/run iterations of your daily workflow.  My sample solution with 2 class libraries and 1 web site went from 17 seconds to build to less than a second.  While these techniques may not be right for every project, the improvements are significant enough that you should try them out and evaluate them for yourself.

Hope this helps,
Brad.

Comments

# Jason said on Wednesday, December 7, 2005 11:08 AM

Personally, the biggest performance increase in compiling I found was to change the projects target platform from "Any CPU" or "Mixed Platforms" to "x86". Went from ~10 seconds to "did it actually compile?.. wow, that was fast."

# D said on Wednesday, October 4, 2006 8:38 AM

I just upgraded my machine :) Compiles in a flash now...

# vahila said on Friday, July 18, 2008 6:26 AM

please add our website

# Gopi said on Wednesday, January 14, 2009 11:03 AM

To find out where your build is slowing down, you could try setting the "MSBuild project build output verbosity:" option to "Diagnostic". This option is available from Tools->Options->Projects and Solutions->Build and Run.

Using that option, I was able to find out that UnRegisterAssembly and RegisterAssembly tasks took the most amount of time during the build of my project, which happens to be an EXE assembly with COM Interop enabled. So to test, I turned off the "Make Assembly COM-Visible" option (Project Properties->Application->Assembly Information) and the build completed significantly faster.

Now I need to figure out how to speed up the unregistering and registering of my assembly as I have to keep COM Interop enabled in my project.