Как принудительно скомпилировать представления ASP.NET MVC?
У меня есть веб-роль Windows Azure, которая содержит веб-сайт с использованием ASP.NET MVC. Когда поступает HTTP-запрос и первая страница загружается, представление (.aspx или.cshtml) компилируется, и это занимает некоторое время, и поэтому при первом обращении к странице это занимает больше времени, чем позднее при обслуживании той же страницы.
Я включил <MvcBuildViews>
(описано в этом ответе), чтобы обеспечить проверку представлений во время компиляции, но это, похоже, не влияет на их компиляцию, когда сайт развернут и работает.
Веб-роли Azure имеют так называемые задачи запуска, а также специальные OnStart()
метод, в котором я могу поместить любой код разминки, поэтому, когда я знаю, что делать, добавление этого в роль не является проблемой.
Есть ли способ форсировать компиляцию всех взглядов?
5 ответов
Оказывается, есть предварительная компиляция ASP.NET, которая может быть выполнена с использованием ClientBuildManager.PrecompileApplication и имитирует поведение компиляции по требованию, но просто компилирует каждую страницу. Пробовал - первая загрузка выглядит заметно быстрее.
Нетривиальная часть - это то, что нужно передать как ClientBuildManager
параметры конструктора. Решение состоит в том, чтобы перечислить все .Applications
из Site
объект и для каждого элемента в .Applications
перечислить все .VirtualDirectories
и использовать Path
а также VirtualPath
от каждого элемента в качестве параметров ClientBuildManager
конструктор.
Взгляните на предварительно скомпилированные Razor Views от David Ebbo
Почему вы хотите это сделать?
Одна из причин сделать это состоит в том, чтобы избежать любого попадания во время выполнения, когда ваш сайт запускается, так как во время выполнения не остается ничего для компиляции. Это может быть важно на сайтах с большим количеством просмотров.
Кроме того, вам больше не нужно развертывать файлы cshtml вообще, что приводит к меньшему набору файлов развертывания.
Еще одно интересное преимущество заключается в том, что он дает вам возможность модульного тестирования ваших представлений, что всегда было чем-то очень сложным в стандартной модели компиляции во время выполнения. Я расскажу об этом более подробно в следующем посте.
Это проблема начальной загрузки или проблема стационарного состояния? Одна из замеченных проблем - это переработка пула приложений, которая по умолчанию составляет 20 минут. Если вы отключите тайм-аут (или установите его на что-то большое), это допустимый обходной путь?
Вот еще один SO-ответ, обсуждающий тайм-аут AppPool и как его отключить. В принципе:
%windir%\system32\inetsrv\appcmd set config -section:applicationPools -applicationPoolDefaults.processModel.idleTimeout:00:00:00
Добавьте это в 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();
}
Если вы используете функциональность публикации в Visual Studio, есть гораздо более простой вариант:
В диалоговом окне " Публикация "> " Параметры" разверните " Параметры публикации файлов" и выберите " Прекомпилировать во время публикации", затем нажмите " Настроить". В диалоговом окне " Дополнительные параметры прекомпиляции" снимите флажок " Разрешить обновление предварительно скомпилированного сайта".
источник: https://msdn.microsoft.com/en-us/library/hh475319.aspx