Оптимизируем ASP.NET MVC 3

Работа с базой данных, как правило, является наиболее узким местом в производительности веб-приложений. Но после оптимизации и кэширования запросов можно пойти дальше и посмотреть на другие части кода. Вот три простых совета, которые помогут ASP.NET MVC приложению обработать еще несколько дополнительных запросов.

Возможность использования советов зависит от того, какие особенности ASP.NET MVC 3 используются. Результат не будет большим (в лучшем случае несколько % производительности) и его сложно точно предугадать. Но, возможно, это станет отправной точкой для ваших исследований. Стоит помнить, что любая оптимизация по разному проявляет себя в конкретных сценариях.

1. Отключите неиспользуемые движки представлений

Когда: Веб-приложение использует встроенные шаблоны отображения и редактирования (например, вызывая методы Html.EditorFor() или Html.DisplayFor()). При этом используется только один тип движка представлений.

Почему: ASP.NET MVC умеет очень хорошо кэшировать запросы к файлам (представления, частичные представления, шаблоны и т.д.). Но в одном случае это не срабатывает – это использование встроенных шаблонов для отображения и редактирования (когда все искомые файлы отсутствуют).

Каждый раз, когда происходит обращение к методам Html.EditorFor() или Html.DisplayFor(), каркас ASP.NET MVC 3 создает требуемый HTML код исходя из метаданных модели. Однако, вначале происходит поиск файлов шаблонов, используя все подключенные движки представлений. И чем больше их зарегистрировано в системе, тем дольше будет поиск. А поскольку файлы не будут найдены, то и результат не попадет в кэш. В результате поиск будет повторяться при каждом обращении к таким страницам.

Как: Если используется только один движок представлений, например Razor, то можно удалить все остальные. Самый простой способ – добавить в метод Application_Start() (файл Global.asax) код:

ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(new RazorViewEngine());

2. Избегайте передачи в представления null вместо модели

Когда: Значение null передается в качестве модели в представление, которое использует строго-типизированных HTML помощников (например, Html.TextBoxFor()). Такое часто можно встретить при разработке страниц для ввода данных.

Почему: Строго-типизированные помощники, такие как Html.TextBoxFor(model => model.Name), попытаются использовать модель в переданных им выражениях. Однако, в этом случае результатом будет выброс исключения NullReferenceException. Его поймает каркас, но на странице с большим количеством подобного кода это может сильно ударить по производительности.

Как: Избежать данной ситуации можно просто передав пустой экземпляр модели:

public ActionResult Insert()
{    
    // return View(); <-- вот этот код передал бы null в качестве модели
    return View(new Product());
}

3. Удалите модуль "URL Rewrite" если вы не используете его

Когда: На сервере установлен модуль "URL Rewrite", но ни одно из веб-приложений его не использует.

Почему: При создании ссылки в некоторых случаях каркас ASP.NET MVC проверяет не был ли исходный запрос изменен модулем "URL Rewrite". Примером может служить вызов метода Html.ActionLink(). Такой подход необходим для того, чтобы генерируемая ссылка была корректной по отношению к исходному запросу.

Процедура проверки подмены URL может быть достаточно ресурсоёмка и включает опрос переменных сервера. Но перед этим ASP.NET MVC 3 определяет и запоминает текущее состояние модуля "URL Rewrite". Если он выключен или не установлен, то проверка подмены URL не производится.

Что произойдет, если реальной подмены URL не было, но "URL Rewrite" включен? В этом случае ASP.NET MVC 3 все равно выполнит полную проверку исходного запроса. Поэтому указанный модуль стоит отключить, даже если фактически он не используется.

Стоит отметить, что ASP.NET MVC 2 всегда выполняет проверку подмены URL, вне зависимости от того, включен или выключен модуль "URL Rewrite".

Как: Удалите или отключите модуль "URL Rewrite".

По материалам заметки: ASP.NET MVC Performance Tips.

Комментарии (2) -

Александр 25.12.2011 18:23:29

1. Уменьшить время поиска файлов

foreach (var viewEngine in ViewEngines.Engines.OfType<VirtualPathProviderViewEngine>())
{
    viewEngine.ViewLocationCache = new DefaultViewLocationCache(TimeSpan.FromHours(24));
}
weblogs.asp.net/.../...-and-performance-issue.aspx

2. Кэширование динамических ресурсов stevesmithblog.com/.../

3. Использовать спрайтинг для png картинок. (Могут быть ошибки при приведении цветов различных форматов)
Sprite and Image Optimization Preview 4 http://aspnet.codeplex.com/releases/view/65787

4. AsyncAction + Library F# with new async sintax. Новый синтаксис включенный в C#5.0 (async, await), уже включен в текущую версию F#.

5. Кеширование на несколько секунд, например одну Action, Controller, Model.

6. Использовать стандартные хелперы, где не нужны шаблоны, что не было лишнего поиска шаблонов. (например, вызывая методы Html.Editor(...) вместо Html.EditorFor(...))

7. На сервере продакшен в machine.config установить в false debug режим. (Для MVC проектов особенно критично, так как количество кода в debug режиме значительно больше)

8. Кеширование ресурсов с указанием версии сборки. (При использовании модуля UrlRewriter и специального хелпера).aboutcode.net/.../...ith-asp-net-mvc-and-iis7.html
<rewrite>
    <rules>
        <rule name="StaticFiles" stopProcessing="true">
            <match url="static/[\d.]+/(.*)$" />
             <action type="Rewrite" url="static/{R:1}" />
            <!-- e.g. "static/1.9.8.4/styles/site.css" -> "static/styles/site.css" -->
        </rule>
    </rules>
</rewrite>

9. Минимизация, слияние файлов JS и CSS и кеширование с помощью библиотеки Combres

10. GZIP

11. Использовать проект glimps для отладки маршрутов и оценки времени их обработки.

12. Собственные JS и CSS файлы сохранять через "сохранить с кодировкой" UTF-8. (Экономит байт от каждого символа)
Var a = null;
Var b = null; => var a=null, b=null; и т.д. (уменьшение размера скриптов)
Использовать один разделитель строки вместо #10#13.

@ Александр: Хорошие советы, вам стоило чуть-чуть подправить текст и опубликовать это как заметку.

Pingbacks and trackbacks (1)+

Добавить комментарий