ASP.NET Core - Precompiling razor views
Improving the startup time of your website is important. There are many reasons for a website to take time to get ready: loading lots of dll, loading data, compiling views, etc. In this post, I'll explain how to reduce the startup time by precompiling razor views.
The view precompilation is a build step that generates a DLL from the cshtml. Instead of doing the view compilation at runtime the first time you hit a view, the compilation is done at build time. This means, the startup time of your website will be reduced.
Of course, you don't want the precompilation process to be hard to set up. So, Microsoft has made a NuGet package to precompile your views (GitHub). Let's see how to use it!
#How to enable razor view precompilation
Add the NuGet package
Microsoft.AspNetCore.Mvc.Razor.ViewCompilation
Edit the
csproj
file and add<MvcRazorCompileOnPublish>true</MvcRazorCompileOnPublish>
csproj (MSBuild project file)<Project ToolsVersion="15.0" Sdk="Microsoft.NET.Sdk.Web"> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>netcoreapp1.1</TargetFramework> <PreserveCompilationContext>true</PreserveCompilationContext> <MvcRazorCompileOnPublish>true</MvcRazorCompileOnPublish> </PropertyGroup>
Publish your site
Shelldotnet restore dotnet publish -c release
You must see a
*.PrecompiledViews.dll
fileASP.NET Core Precompiled views dll
It's so easy 😃
#What contains the PrecompiledViews dll
If you are curious, you may wonder what's in the dll. The dll contains a class per view. The class generated from a view contains some properties and one method: ExecuteAsync
. This method calls the Write
and WriteLiteral
methods, plus some additional method calls for infrastructure support.
@model Page
@{ var page = Model; }
<div class="page">
@Html.Raw(page.Content)
</div>
namespace AspNetCore
{
public class _Views_Blog_Page_cshtml : RazorPage<Page>
{
[RazorInject]
public IModelExpressionProvider ModelExpressionProvider { get; private set; }
[RazorInject]
public IUrlHelper Url { get; private set; }
[RazorInject]
public IViewComponentHelper Component { get; private set; }
[RazorInject]
public IJsonHelper Json { get; private set; }
[RazorInject]
public IHtmlHelper<Page> Html { get; private set; }
public override async Task ExecuteAsync()
{
Page model = this.Model;
this.BeginContext(91, 24, true);
this.WriteLiteral((object) "<div class=\"page\">\r\n ");
this.EndContext();
this.BeginContext(116, 22, false);
this.Write((object) this.Html.Raw(model.Content));
this.EndContext();
this.BeginContext(138, 8, true);
this.WriteLiteral((object) "\r\n</div>");
this.EndContext();
}
}
}
The code can be more complex if your view contains more code or tag helpers.
#Conclusion
Depending on the number of pages available on your website, you will see a reduction in the startup time. Even if you don't have a lot of pages, it's so easy to integrate that you should enable it anyway 😃
Do you have a question or a suggestion about this post? Contact me!