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

时间:2022-03-28 07:08:59

I have a Windows Azure web role that contains a web site using ASP.NET MVC. When an HTTP request arrives and a page is first loaded the view (.aspx or .cshtml) is compiled and that takes some time and so the first time a page is served it takes notable longer than later serving the same page.

我有一个Windows Azure Web角色,其中包含使用ASP.NET MVC的网站。当HTTP请求到达并且首次加载页面时,视图(.aspx或.cshtml)被编译并且花费一些时间,因此第一次提供页面时,它比后来服务同一页面花费更长的时间。

I've enabled <MvcBuildViews> (described in this answer) to enforce compile-time validation of views, but that doesn't seem to have any effect on their compilation when the site is deployed and running.

我启用了 (在本回答中描述)来强制执行视图的编译时验证,但是在部署和运行站点时,这似乎对它们的编译没有任何影响。

Azure web roles have so-called startup tasks and also a special OnStart() method where I can place whatever warmup code, so once I know what to do adding that into the role is not a problem.

Azure Web角色有所谓的启动任务,还有一个特殊的OnStart()方法,我可以放置任何热身代码,所以一旦我知道该怎么做,将其添加到角色中不是问题。

Is there a way to force compilation of all views?

有没有办法强制编译所有视图?

5 个解决方案

#1


14  

Take a look at Precompiled Razor Views by David Ebbo

看看David Ebbo的预编译Razor Views

Why would you want to do that?

你为什么想这么做?

One reason to do this is to avoid any runtime hit when your site starts, since there is nothing left to compile at runtime. This can be significant in sites with many views.

这样做的一个原因是为了避免在站点启动时遇到任何运行时命中,因为在运行时没有任何东西可以编译。这在具有许多视图的站点中可能很重要。

Also, you no longer need to deploy the cshtml files at all, resulting in a smaller deployment file set.

此外,您根本不再需要部署cshtml文件,从而导致部署文件集较小。

Another cool benefit is that it gives you the ability to unit test your views, which has always been something very difficult with the standard runtime compilation model. I’ll cover that in more details in a future post.

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

#2


7  

Turns out there's ASP.NET Precompilation that can be performed using ClientBuildManager.PrecompileApplication and mimics the on-demand compilation behavior, but just compiles every page. Tried it - the first load looks notably faster.

事实证明,可以使用ClientBuildManager.PrecompileApplication执行ASP.NET预编译,并模拟按需编译行为,但只编译每个页面。尝试过 - 第一个负载看起来更快。

The non-trivial part is what to pass as ClientBuildManager constructor parameters. The solution is to enumerate all .Applications of the Site object and for each item in .Applications enumerate all .VirtualDirectories and use Path and VirtualPath from each item as parameters to ClientBuildManager constructor.

非平凡部分是作为ClientBuildManager构造函数参数传递的内容。解决方案是枚举Site对象的所有.Applications以及.Applications中的每个项目枚举所有.VirtualDirectories并使用每个项目中的Path和VirtualPath作为ClientBuildManager构造函数的参数。

#3


3  

Is this an initial-load issue or a steady-state issue? One issue seen is that of app pool recycling, which defaults to 20 minute timeout. If you disable timeout (or set it to something large), is that a valid workaround?

这是初始负载问题还是稳态问题?看到的一个问题是应用程序池回收,默认为20分钟超时。如果禁用超时(或将其设置为大型),这是一种有效的解决方法吗?

Here's another SO answer discussing AppPool timeout and how to disable it. Basically:

这是另一个SO答案,讨论AppPool超时以及如何禁用它。基本上:

%windir%\system32\inetsrv\appcmd set config -section:applicationPools -applicationPoolDefaults.processModel.idleTimeout:00:00:00

#4


1  

Add this to OnStart:

将其添加到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();
        }

#5


0  

If you use the Publish functionnality of Visual Studio, there is a much simpler option :

如果您使用Visual Studio的Publish功能,则有一个更简单的选项:

On the Publish dialog > Settings pane, expand File Publish Options and check Precompile during publishing then click configure. On the Advanced Precompile Settings dialog box, uncheck Allow precompiled site to be updatable.

在“发布”对话框>“设置”窗格上,展开“文件发布选项”并选中“发布期间预编译”,然后单击“配置”。在“高级预编译设置”对话框中,取消选中“允许预编译的站点可更新”。

source: https://msdn.microsoft.com/en-us/library/hh475319.aspx

来源:https://msdn.microsoft.com/en-us/library/hh475319.aspx

#1


14  

Take a look at Precompiled Razor Views by David Ebbo

看看David Ebbo的预编译Razor Views

Why would you want to do that?

你为什么想这么做?

One reason to do this is to avoid any runtime hit when your site starts, since there is nothing left to compile at runtime. This can be significant in sites with many views.

这样做的一个原因是为了避免在站点启动时遇到任何运行时命中,因为在运行时没有任何东西可以编译。这在具有许多视图的站点中可能很重要。

Also, you no longer need to deploy the cshtml files at all, resulting in a smaller deployment file set.

此外,您根本不再需要部署cshtml文件,从而导致部署文件集较小。

Another cool benefit is that it gives you the ability to unit test your views, which has always been something very difficult with the standard runtime compilation model. I’ll cover that in more details in a future post.

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

#2


7  

Turns out there's ASP.NET Precompilation that can be performed using ClientBuildManager.PrecompileApplication and mimics the on-demand compilation behavior, but just compiles every page. Tried it - the first load looks notably faster.

事实证明,可以使用ClientBuildManager.PrecompileApplication执行ASP.NET预编译,并模拟按需编译行为,但只编译每个页面。尝试过 - 第一个负载看起来更快。

The non-trivial part is what to pass as ClientBuildManager constructor parameters. The solution is to enumerate all .Applications of the Site object and for each item in .Applications enumerate all .VirtualDirectories and use Path and VirtualPath from each item as parameters to ClientBuildManager constructor.

非平凡部分是作为ClientBuildManager构造函数参数传递的内容。解决方案是枚举Site对象的所有.Applications以及.Applications中的每个项目枚举所有.VirtualDirectories并使用每个项目中的Path和VirtualPath作为ClientBuildManager构造函数的参数。

#3


3  

Is this an initial-load issue or a steady-state issue? One issue seen is that of app pool recycling, which defaults to 20 minute timeout. If you disable timeout (or set it to something large), is that a valid workaround?

这是初始负载问题还是稳态问题?看到的一个问题是应用程序池回收,默认为20分钟超时。如果禁用超时(或将其设置为大型),这是一种有效的解决方法吗?

Here's another SO answer discussing AppPool timeout and how to disable it. Basically:

这是另一个SO答案,讨论AppPool超时以及如何禁用它。基本上:

%windir%\system32\inetsrv\appcmd set config -section:applicationPools -applicationPoolDefaults.processModel.idleTimeout:00:00:00

#4


1  

Add this to OnStart:

将其添加到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();
        }

#5


0  

If you use the Publish functionnality of Visual Studio, there is a much simpler option :

如果您使用Visual Studio的Publish功能,则有一个更简单的选项:

On the Publish dialog > Settings pane, expand File Publish Options and check Precompile during publishing then click configure. On the Advanced Precompile Settings dialog box, uncheck Allow precompiled site to be updatable.

在“发布”对话框>“设置”窗格上,展开“文件发布选项”并选中“发布期间预编译”,然后单击“配置”。在“高级预编译设置”对话框中,取消选中“允许预编译的站点可更新”。

source: https://msdn.microsoft.com/en-us/library/hh475319.aspx

来源:https://msdn.microsoft.com/en-us/library/hh475319.aspx