If you've recently started a new ASP.NET Core 2.1 project, or upgraded an existing project, and your username contains a space, you may find your builds and compilation is very slow. This post explains how to dramatically speed things up.
Razor has received some new features in ASP.NET Core 2.1. The big one is that you can now create Razor class libraries that let you use Razor to create reusable components, views, and pages for your web applications.
To enable this, the building, packaging, and publishing of Razor files in ASP.NET Core projects has been standardized with a new Razor SDK.
Changes in Razor SDK Build Process
One significant difference between the Razor SDK build process and the previous method, is that the Razor SDK has
RazorCompileOnBuild set to
true by default.
This means that all your Razor files are now compiled and output as an assembly at build-time, instead of being compiled on-demand as they were previously.
This is definitely what you want in production as it speeds up the start-up of your websites and is something that I enabled manually in previous versions of ASP.NET Core.
Furthermore, it means you get compile time error checking of your Razor files during development. Compile time errors are much better than runtime errors.
RazorCompileOnBuild seems to slow compilation down massively.
In a new ASP.NET Core 2.1 project with only a handful of Razor view files, I found compilation was taking 48 seconds!
RazorCompileOnBuild, compilation was instantaneous (mere milliseconds).
After some deep digging, it turns out, the issue is that the Razor Build Server does not like usernames containing spaces.
To speed up your build, right click on your project in Solution Explorer, and select
<UseRazorBuildServer>false</UseRazorBuildServer> as a child of the
PropertyGroup element as follows:
<PropertyGroup> <TargetFramework>netcoreapp2.1</TargetFramework> <UseRazorBuildServer>false</UseRazorBuildServer> </PropertyGroup>
That's it. You should now have lightning fast compilations again.
Furthermore, Razor is still compiled ahead of time using the in-process compiler, so you still get compile time error checking and fast site start-up in production.
How to Debug
In case you run into similar problems and want to debug them yourself, here is how I debugged it.
I didn't believe that compiling should be this slow.
I started by doing some searches on Google, then some searches on the relevant GitHub repositories, and finally, when those turned up nothing, I went to read the release notes for ASP.NET Core 2.1.
In the release notes, I found the changes to Razor, including
My first step was to disable
RazorCompileOnBuild and sure enough, compilation was fast again.
At this stage, I suspected that something is failing during Razor compilation and that it ends up waiting for some timeout to occur.
I then checked with David Fowler from the ASP.NET team at Microsoft to see if this was a known issue, but David hadn't seen it before.
To dig deeper, I started by creating a simple repro of the issue.
I found that I could consistently reproduce the issue on Visual Studio 2017 v15.7.4 as follows:
- In Visual Studio, open
.NET Coretab and select
ASP.NET Core Web Application.
- Select the
Web Application (Model-View-Controller)template and
ASP.NET Core 2.1.
- Right Click on
At this point, compilation takes 45 seconds and is the same on every rebuild.
If I modified the
csproj and added
<RazorCompileOnBuild>false</RazorCompileOnBuild>, rebuilds became very quick.
dotnet Command Line
As a further experiment, I took the same project and tried compiling from the command line by executing the following commands:
The command line build process takes 44.81 seconds according to its own timer. I ran this process three times and the times were consistent: 44.81, 44.81, and 44.84 seconds.
After disabling Razor compilation on build, I ran the command line build process three more times and the times were consistently fast: 2.13, 2.10, and 2.12 seconds.
I then ran
dotnet build -v diag to check out the diagnostics. It shows 20888ms in
RazorCoreGenerate and 21455ms in
ResolveTagHelperRazorGenerateInputs, which correspond to the task times for
I then went looking through the logs. The only suspicious lines that I found were:
Server execution failed with response Rejected. For more info, check the server log file in the location specified by the RAZORBUILDSERVER_LOG environment variable. (TaskId:60)
Fallback to in-process execution.
Server execution failed with response Rejected. For more info, check the server log file in the location specified by the RAZORBUILDSERVER_LOG environment variable. (TaskId:66)
Fallback to in-process execution. (TaskId:66)
So, the issue seems to be with the Razor Build Server failing and then resolving itself with the fallback after a 20 second time out. It does this twice, and hence why I was getting >40 second build times.
At this point, I decided to try disabling the Razor Build Server using
<UseRazorBuildServer>false</UseRazorBuildServer> instead of disabling the Razor compilation entirely with
Success! The builds are now fast with Razor compilation. The issue is with the Razor Build Server.
At this point, I had completed my investigations and was ready to file a GitHub issue.
With my new found knowledge, I started by conducting some new searches and turned up this issue.
It seems that others have experienced the same problem and have already taken it a little further, to discover that the issue occurs when you have a space in your Windows username.
The fix has already been committed and the patch will make its way into a future ASP.NET Core 2.1 release.
In the interim, you can work around the issue by disabling the build server using
<UseRazorBuildServer>false</UseRazorBuildServer> as described earlier in this post.