Данное руководство устарело. Актуальное руководство: Руководство по ASP.NET Core
Кэширование контента может играть важную роль в работе приложения. С помощью кэширования мы можем уменьшить количество обращений к базе данных, оптимизировать обработку запросов и тем самым уменьшить нагрузку на сервер и повысить производительность.
Наиболее простой способ кэширования данных представляет использование атрибута OutputCache.
Данный атрибут может применяться как к всему контроллеру, так и к отдельным его методам. Применение атрибута к контроллеру позволяет задать единую политику кэширования ко всем методам данного контроллера.
Действие атрибута OutputCache можно настроить с помощью его свойств:
CacheProfle: определяет конфигурацию кэширования
Duration: продолжительность кэширования контента в секундах. Важно оптимально подобрать временной отрезок, так как если задать большое значение, то пользователи будут работать практически со статичными данными, а при очень маленьком значении будет слишком часто обновление кэша, что нивелирует преимущества его использования
Location: место, где размещается кэшированный контент
NoStore: если данное значение равно true
, в ответе в заголовке Cache-Control
устанавливается флаг
no-store
, что указывает браузеру, что контент не надо сохранять
SqlDependency: определяет зависимость между кэшем и таблицой в бд
VaryByCustom: указывает произвольное значение, по которому будут определяться различные версии кэшированных данных
VaryByHeader: указывает на набор заголовков, по которым будут определяться различные версии кэшированных данных
VaryByParam: указывает на параметры строки запроса или параметры переданных форм, по которым будут определяться различные версии кэшированных данных
С помощью свойства Location
можно определить в качестве хранилища кэшированного контента как сервер, так и браузер клиента. В частности, данное свойство
может принимать одно из значений перечисления System.Web.UI.OutputCacheLocation
:
Any
: контент кэшируется как на клиенте, так и на прокси-сервере и в выходном кэше сервера
Client
: контент кэшируется на клиенте
Downstream
: контент кэшируется как на клиенте, так и на прокси-сервере. Выходной кэш сервера не используется
None
: для заголовка Cache-Control
устанавливается значение no-cache
, что значит, что контент не будет нигде кэшироваться
Server
: контент кэшируется только в выходном кэше сервера
ServerAndClient
: контент кэшируется на клиенте и в выходном кэше сервера
Рассмотрим на примере:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.Mvc; namespace CachingApp.Controllers { public class HomeController : Controller { static int x = 9; [OutputCache(Duration=30, Location= OutputCacheLocation.Downstream)] public string Index() { x++; return x.ToString(); } } }
Для простоты примера в данном случае выводится в браузере значение статической переменной. При обычной работе без кэширования при каждом обращении к данному
методу значение этой переменной увеличивалось бы на единицу. Но здесь используется атрибут OutputCache
, который задает, во-первых, время
кэширования - 30 секунд, во-вторых, место кэша - клиент и возвожные прокси-серверы, через которые может идти запрос.
В итоге несмотря на новые обращения к ресурсу в пределах 30 секунд мы будем получать одно и то же значение переменной x
, потому что ее значение
будет браться из кэша. И только через 30 секунд эта переменная может инкрементироваться.
Мы можем проинспектировать заголовки ответа в браузере (например, в IE):
При получении кэшированных данных мы получим статусный код 304, а затраченное на запрос время будет очень небольшим (в данном случае не более 1 мс), так как данные будут браться из кэша браузера.
Подобным образом мы можем ограничиться кэшированием на сервере:
public class HomeController : Controller { static int x = 9; [OutputCache(Duration=30, Location= OutputCacheLocation.Server)] public string Index() { x++; return x.ToString(); } }
Тот же метод, только кэширование ограничено кэшом сервера. В отличие от предыдущего примера здесь уже запрос идет от браузера к серверу, но после кэширования в течение следующих 30 секунд при повторных обращениях к методу данный метод не будет срабатывать: он просто будет отдавать клиенту данные, которые есть в кэше:
При повторных обращениях опять же время довольно мало - в данном случае всего 15 миллисекунд.
Хотя время выполнения данного метода очень мало в силу его простоты - простой инкремент переменной, но в реальности методы, естественно, будут намного сложнее, с выборкой из базы данных, обращением к различным ресурсам и сложных вычислениях. И тут кэширование действительно сможет реально оптимизировать работу сервера.