从ASP.NET Core 2.1中的类库导入Razor视图时,第一个请求很慢

问题描述 投票:0回答:1

在ASP.NET Core 2.1中,我有一个带有Razor视图的DLL项目(Microsoft.NET.Sdk),用于与多个应用程序共享通用的局部视图,例如导航,页脚等。它的创建类似于described here。因此,我有一个ASP.NET Core 2.1 MVC应用程序,其中包括那些库并嵌入部分视图。

虽然这可行,但我注意到此应用程序的首页加载时间大大增加了。主HTML文档花了大约3秒钟。随后的请求非常快(〜30-40ms)。我尝试删除了由共享DLL嵌入的应用程序中的所有部分视图。现在,第一个请求要快得多(大约300毫秒)。

因此,这似乎是由于从共享DLL项目中加载Razor视图引起的。我尝试使用类似的方法在AppStartup方法中预加载程序集(从this question启发):

GC.KeepAlive(typeof(Assets.AssetStartup));
System.Reflection.Assembly.Load("Assets"); 

在性能上没有太大差异,第一次请求仍然花费了约2.9秒。

我该如何改善?

我知道从EntityFramework进行预热,因此,我有了以类似方式解决此问题的想法。但是我不确定它到底在哪里减慢我的应用程序的速度:是程序集的加载(并且我的预取尝试在某种程度上是错误的),还是仍然与Razor编译有关?

因为我也知道通过预编译Razor视图来提高性能。在ASP.NET Core 1中,我手动启用了此功能,第一个请求明显更快。由于Microsoft重新编写了此部分并默认情况下启用了预编译,但是我的Razor DLL应用程序未生成名为{AppName}.Views.dll的文件(MVC应用程序具有该文件),因此我不确定这是否是问题所在。

c# asp.net-core razor dll asp.net-core-2.1
1个回答
0
投票

Some posts以及blog posts表示Razor lib项目上的预编译存在问题。但是我记得from the .NET Core docs在3.0中不推荐使用MvcRazorCompileOnPublish并将其删除。它禁用了新的Razor SDK。这对我来说似乎不是一个可靠的解决方案。

因此,我创建了一个空的Razor项目,并将csproj文件与我的lib项目进行了比较。它显示了它引用了我项目中的Microsoft.NET.Sdk.Razor而不是Microsoft.NET.Sdk(作为常规.NET核心Core类库创建)。更新了SDK之后,我的Debug文件夹还包含一个Assets.Views.dll文件,该文件指示已进行预编译。

它也是NuGet所添加的,可以通过使用7zip打开.nupkg文件来轻松地进行验证。 lib/netcoreapp2.1文件夹现在也包含.Views.dll

此解决方案将第一个请求呈现时间从〜3秒缩短到1.1秒。与没有外部DLL的300ms相比,速度要快得多,但要慢得多。我认为这是解决方案的一部分,但似乎还有其他瓶颈会减慢第一个请求的速度。我对其他如何改善最后延迟的想法持开放态度。

我目前仅包含来自Razor DLL的四个局部视图。其中一个具有108行html,带有一点动态剃刀逻辑和两个注入的服务。其他的则小得多,并且还不包含很多动态逻辑。我还尝试不包括较大的局部视图,也没有明显的区别。

我不敢相信,从外部Razor lib获得四个相对较小的局部视图会将第一请求延迟了800ms。当视图位于同一项目的本地时,情况并非如此。

预加载不是问题

找到带有列出所有已加载程序集的代码段的a blog entry from Rick Strahl

var assemblies = AppDomain.CurrentDomain.GetAssemblies();
foreach (var assembly in assemblies) {
    Console.WriteLine(assembly.GetName());
}

我在使用Razor DLL的应用程序的ConfigureService中运行了此文件。它显示了我的Razor DLL文件(资产 Assets.Views)中的both程序集。我认为是这种情况,因为我获取了程序集信息以将其作为EmbeddedFileProvider传递给RazorViewEngineOptions。但是,这说明了为什么我的预加载尝试对页面生成时间没有任何影响。

© www.soinside.com 2019 - 2024. All rights reserved.