ASP.NET Core - Precompiling razor views

 
 
  • Gérald Barré

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

  1. Add the NuGet package Microsoft.AspNetCore.Mvc.Razor.ViewCompilation

  2. 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>
  3. Publish your site

    Shell
    dotnet restore
    dotnet publish -c release
  4. You must see a *.PrecompiledViews.dll file

    ASP.NET Core Precompiled views dllASP.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.

HTML
@model Page
@{ var page = Model; }
<div class="page">
    @Html.Raw(page.Content)
</div>
C#
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!

Follow me:
Enjoy this blog?Buy Me A Coffee💖 Sponsor on GitHub