簡體   English   中英

從 ASP.NET Core 2.1 中的 class 庫中導入 Razor 視圖時,第一次請求很慢

[英]First request slow when importing Razor views from class library in ASP.NET Core 2.1

In ASP.NET Core 2.1, I have a DLL project ( Microsoft.NET.Sdk ) with Razor views for sharing common partial views like navigation, footer, ... with multiple applications. 它是像這里描述的那樣創建的。 所以我有一個包含這些庫並嵌入部分視圖的 ASP.NET Core 2.1 MVC 應用程序。

雖然這可行,但我注意到此應用程序的首頁加載時間大幅增加。 主 HTML 文檔大約需要 3 秒。 隨后的請求非常快(~30-40ms)。 我嘗試刪除共享 DLL 嵌入的應用程序中的所有部分視圖。 現在第一個請求要快得多(大約 300 毫秒)。

所以它似乎是由於從共享的 DLL 項目加載 Razor 視圖引起的。 我嘗試在 AppStartup 方法中使用不同的方法預加載程序集(靈感來自這個問題):

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

性能上沒有太大差異,第一次請求仍然需要大約 2.9 秒。

我該如何改進呢?

我知道從 EntityFramework 開始熱身,因此,我有想法以類似的方式解決這個問題。 但我不確定它到底在哪里減慢了我的應用程序:是程序集的加載(並且我的預取嘗試在某種程度上是錯誤的),還是仍然與 Razor 編譯有關?

因為我還通過預編譯 Razor 視圖了解了性能改進。 在 ASP.NET Core 1 中,我手動啟用了此功能,第一個請求明顯更快。 由於微軟重新編寫了這部分並默認啟用了預編譯,但我的 Razor DLL 應用程序不會生成名為{AppName}.Views.dll的文件問題。

一些帖子博客帖子表明 Razor lib 項目的預編譯存在問題。 但我從 .NET Core 文檔中記得MvcRazorCompileOnPublish在 3.0 中已被棄用和刪除。 它會禁用新的 Razor SDK。 這對我來說似乎不是一個可靠的解決方案。

所以我創建了一個空的 Razor 項目,並將 csproj 文件與我的 lib 項目進行了比較。 It shows that it references Microsoft.NET.Sdk.Razor instead of Microsoft.NET.Sdk from my project (created as a regululr .NET core Core class library). 更改 SDK 后,我的Debug文件夾還包含一個Assets.Views.dll文件,表示預編譯。

NuGet 也添加了它,可以通過使用 7zip 打開 .nupkg 文件輕松驗證。 lib/netcoreapp2.1文件夾現在也包含.Views.dll

此解決方案將首次請求渲染時間從約 3 秒提高到 1.1 秒。 快得多,但與沒有外部 DLL 的 300 毫秒相比仍然慢得多。 我認為這是解決方案的一部分,但似乎還有其他瓶頸會減慢第一個請求。 我對如何改善最后一次延遲的其他想法持開放態度。

我目前僅包含來自 Razor DLL 的四個部分視圖。 一個有 108 行 html 和一點動態 razor 邏輯和兩個注入服務。 其他的要小得多,還不包含很多動態邏輯。 我也嘗試不包括較大的局部視圖,沒有明顯的區別。

我不敢相信包括來自外部 Razor 庫的四個相對較小的部分視圖會將第一個請求延遲 800 毫秒。 當視圖在本地位於同一項目中時,情況並非如此。

預加載不是問題

找到Rick Strahl 的博客條目,其中包含列出所有已加載程序集的片段:

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

我在使用 Razor DLL 的應用程序的ConfigureService中運行了這個。 它顯示我的 Razor DLL 文件(AssetsAssets.Views)中的兩個程序集。 我認為是這種情況,因為我獲取程序集信息以將其作為EmbeddedFileProvider傳遞給RazorViewEngineOptions 但是,它解釋了為什么我的預加載嘗試對頁面生成時間沒有任何影響。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM