美文网首页
Asp.net MVC 为你的网站开启预编译

Asp.net MVC 为你的网站开启预编译

作者: Hooke_718b | 来源:发表于2019-01-19 17:10 被阅读0次

为你的网站开启预编译

为什么做预编译?

最重要的原因是性能。

razor views 默认是在运行时才编译的。在项目里有很多 view 的情况下,这将会使你的 web 应用程序启动时间更长。为了更好的性能,预编译你的 razor views 就是一个理想的方案。

即使性能不是标准,并且其实你也并没有很多的页面,你也应该为你的 web 应用程序的性能考虑考虑,让 razor views 在项目构建时编译,而不是运行时编译。 正常情况下,只有是在你打开这个页面时你才能看到页面的编译错误。即使你犯了一些低级错误你也不会知道,直到你的应用程序出问题时你才发现。这时,你会希望,如果能有一个在项目构建时就能对 razor views 进行编译检查是多么好的一件事啊。

注意在编译 razor views 时,将在这里描述,而不是即将编译他们时。MVC 默认有一个MvcBuildViews特性设置,当在你的项目文件 csproj 里把默认的<MvcBuildViews>false</MvcBuildViews>改为true时,你可以在编译项目时编译你的 razor views。但是,这个只能用于在你的 views 里捕获编译错误,并且它并不是我们说的预编译。如果你不想预编译,又能忍受这个,只要在 csproj 文件里改变这一行即可。

对视图进行预编译稍微复杂一些。但是,MvcBuildViews会减慢你的项目构建速度(也许这就是它默认为 false 的原因)。这并不是我们要谈的预编译处理技术。在我们的项目中,只会有越来越多的页面,在项目构建时预编译所用时间将要比使用MvcBuildViews所花的构建时间快 50%。这是你可以省去非常多的构建时间。

其他原因是使用预编译时,你并不需要发布所有的这些.cshtml 文件到 web 服务器中。这将减少部署时间,尤其是对于有许多视图文件的项目。

希望这些理由可以说服你,使用预编译视图是非常有用处的。下面我将会讨论如何来实现这一点。我们将使用一个神奇的库叫做RazorGenerator


如何做?

在这之前,先用 Nuget 安装RazorGenerator.MvcRazorGenerator.MsBuild两个包到你的项目里。

RazorGenerator.Mvc包带来了PrecompiledMvcEngine并且会注册为一个 ViewEngine 到你的 mvc 项目中。它会放在App_Start目录下的RazorGeneratorMvcStart类里面:

[assembly: WebActivator.PostApplicationStartMethod(typeof(MvcApplication1.App_Start.RazorGeneratorMvcStart), "Start")]

namespace MvcApplication1.App_Start {
    public static class RazorGeneratorMvcStart {
        public static void Start() {
            var engine = new PrecompiledMvcEngine(typeof(RazorGeneratorMvcStart).Assembly) {
                UsePhysicalViewsIfNewer = HttpContext.Current.Request.IsLocal
            };

            ViewEngines.Engines.Insert(0, engine);

            // StartPage lookups are done by WebPages.
            VirtualPathFactoryManager.RegisterVirtualPathFactory(engine);
        }
    }
}

它使用WebActivator添加PrecompiledMvcEngine作为一个视图引擎到你的项目里。请注意这条线UsePhysicalViewsIfNewer = HttpContext.Current.Request.IsLocal.这使你能够像以前那样使用预编译的 razor 视图进行开发.当你修改了一个 razor 文件时,你不需要编译你的项目,只需要刷新你的程序就能看到这些变化了。从这条线我们可以看出,如果.cshtml 发生了变化,它将会使用这些新的来代替之前预编译的版本。这意味着无缝过滤到预编译视图。干净利索!

现在,让我们获取最精彩的部分——在编译时,将预编译与视图连接起来。这就是RazorGenerator.MsBuild的包.它提供了 msbuild targets 文件用来连接到你的项目中以用来预编译 razor views。

它将会随着RazorGenerator.MsBuild的包安装完成以后,自动穿插到你的项目文件中:

<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" Condition="false" />
<Import Project="$(SolutionDir)\packages\RazorGenerator.MsBuild.1.5.0.0\tools\RazorGenerator.targets"/>

第二个导入的只需要添加一次。这时,如果你之前开启了MvcBuildViews,那么就把它关掉吧,现在已经不需要它了。

就这些!你现在可以构建你的应用程序并且视图会预编译了。你可以尝试在页面里写一个错误的 c#代码,看看它在编译时能不能检查编译错误了。这些预编译的文件将会生成在obj\CodeGen目录下面。

有一件事你必须做,如果你不想包括视图作为部署包的一部分。默认,.cshtml 文件会以内容类型方式创建。而部署时,web 应用程序会将所有的内容类型作为目标,发布到站点目录下。所以,你需要改变Build Action,将这些视图不包括在内。这可以很容易地自动化,而不用改变视图的属性。只需要像下面这样添加一段代码到你的 csproj 文件中即可。

<Import Project="$(SolutionDir)\packages\RazorGenerator.MsBuild.1.5.0.0\tools\RazorGenerator.targets"/>
<Target Name="BeforeBuild">
    <ItemGroup>
      <Content Remove="Views\**\*.cshtml" />
      <None Include="Views\**\*.cshtml" />
    </ItemGroup>
</Target>

我添加了BeforeBuild Target 在the RazorGenerator.targets的后面。BeforeBuild target提供了在pre-build事件之前要做的事情。现在我们把移除所有的.cshtml 从内容类型中移除,并设置为不引入。现在,当应用程序构建时,页面就再也不会以内容类型拷贝到发布目录里了。

这就是所有要做的事情。

That’s all there is to it.

https://stacktoheap.com/blog/2013/01/19/precompiling-razor-views-in-asp-dot-net-mvc-3/

相关文章

网友评论

      本文标题:Asp.net MVC 为你的网站开启预编译

      本文链接:https://www.haomeiwen.com/subject/ixezdqtx.html