Как принудительно скомпилировать представления 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

Другие вопросы по тегам