如何强制编译ASP.NET MVC视图?

16
我有一个Windows Azure Web角色,其中包含使用ASP.NET MVC的网站。当HTTP请求到达并首次加载页面时,视图(.aspx或.cshtml)会被编译,这需要一些时间,因此第一次提供页面比稍后提供相同页面要花费更长的时间。
我已启用(在此答案中描述)来强制在编译时验证视图,但似乎对其在站点部署和运行时的编译没有任何影响。
Azure Web角色有所谓的启动任务,还有一个特殊的OnStart()方法,我可以在其中放置任何预热代码,因此一旦知道该怎么做,将其添加到角色中就不是问题。
是否有一种方法可以强制编译所有视图?
5个回答

15

请看David Ebbo的预编译Razor视图

为什么要这样做?

这样做的一个原因是避免网站启动时出现任何运行时影响,因为在运行时不需要再编译任何内容。在具有许多视图的网站中,这可能很重要。

此外,您不再需要完全部署cshtml文件,从而使部署文件集更小。

另一个很酷的好处是它使您能够对视图进行单元测试,这一直是标准运行时编译模型非常困难的事情。我将在未来的文章中详细介绍这个问题。


我不确定,因为我只在 Razor 视图中使用过它。 - archil

8
原来可以使用 ClientBuildManager.PrecompileApplication 进行 ASP.NET 预编译,模拟按需编译行为,但是会编译每个页面。我试过了——第一次加载速度明显更快。
关键是如何将参数传递给 ClientBuildManager 构造函数。解决方案是枚举 Site 对象的所有 .Applications,并对于 .Applications 中的每个项目,枚举所有 .VirtualDirectories 并使用每个项目中的 PathVirtualPath 作为 ClientBuildManager 构造函数的参数。

在创建ClientBuildManager类时,您提供哪些字符串作为参数? - trailmax
1
@trailmax:我获取应用程序的VirtualDirectory对象,从中获取作为第一个参数的Path和作为第二个参数的PhysicalPath。 - sharptooth

3
这是一个初始加载问题还是稳态问题?其中一个问题是应用程序池回收,默认超时时间为20分钟。如果禁用超时(或将其设置为较大值),是否有效解决?
这里有另一个SO答案讨论了AppPool超时以及如何禁用它。基本上:
%windir%\system32\inetsrv\appcmd set config -section:applicationPools -applicationPoolDefaults.processModel.idleTimeout:00:00:00

这是另一个我毫无头绪的问题。非常感谢。然而,我正在询问关于将ASP.NET视图编译为可执行代码的编译,这仍然需要完成,无论apppool是否被回收。你有任何想法吗?为什么首先要进行回收呢?我的意思是,我部署Web角色以始终拥有网站。为什么会被回收呢? - sharptooth
应用程序池回收与Windows Server应用程序池回收相同。我看到有人主张在Windows Azure上更改此设置,但这将导致本地的Windows Server和Windows Azure之间存在不一致性,而我们的目标是保持一致性。在高流量场景下,您可能不会遇到回收问题。使用上述代码很容易进行调整,并且无论是在本地还是在云中都可以正常工作。 - David Makogon

1
将以下内容添加到 OnStart 中:
  using (var serverManager = new ServerManager())
        {
            string siteName = RoleEnvironment.CurrentRoleInstance.Id + "_" + "Web";
            var siteId = serverManager.Sites[siteName].Id;
            var appVirtualDir = $"/LM/W3SVC/{siteId}/ROOT";  // Do not end this with a trailing /

            var clientBuildManager = new ClientBuildManager(appVirtualDir, null, null,
                                        new ClientBuildManagerParameter
                                        {
                                            PrecompilationFlags = PrecompilationFlags.Default,
                                        });

            clientBuildManager.PrecompileApplication();
        }

0
如果您使用 Visual Studio 的发布功能,那么有一个更简单的选项:
在“发布”对话框 > “设置”面板上,展开“文件发布选项”,然后勾选“发布期间预编译”,然后单击“配置”。在“高级预编译设置”对话框中,请取消选中“允许可以更新预编译站点”选项。
来源: https://msdn.microsoft.com/en-us/library/hh475319.aspx

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接