Статьи

Кэширование динамических страниц с ASP.NET

Заинтересованы в .NET? Не пропустите .NET Feature Guide — это отличный ресурс!

Кэширование — это метод сохранения данных в какой-либо форме памяти (обычно на компьютере, а не в вашей) с целью ускорения времени, необходимого для доступа к этим данным. Когда вы открываете страницу, ваш браузер кэширует страницу на вашем компьютере, так что если вы нажмете кнопку «Назад», ему не придется загружать файлы подкачки снова.

Это не новая концепция — производители процессоров занимаются этим годами, но исторически сложное кэширование динамических веб-страниц было сложной и неуправляемой задачей для разработчиков. Многие люди выполняли кеширование, используя Application State в ASP или стороннее программное обеспечение.

Почему вы хотите кэшировать?

Привлекательность кэширования заключается в том, что он может повысить производительность приложения. Представьте себе страницу, которая отправляла запрос в базу данных 30000 раз в день. С помощью кэширования вы можете сократить это до 1 запроса в день, даже один раз в неделю!

Это привлекательность кеширования!

ASP.NET предлагает много разных способов кеширования информации и контроля, когда это происходит и что кешируется. Используя механизмы , поддерживающие HTTP 1.1 , ASP.NET может кэшировать страницы в браузере (на самом деле на компьютере клиента), прокси-серверах и веб-сервере, на котором находится приложение. Вы можете кэшировать целые страницы, разделы страниц и даже объекты, созданные в вашем коде (DataSets, Web Services)! И все это занимает одну строку кода! Возможно, это одна из моих любимых функций ASP.NET!

Из-за огромного размера кэширующих возможностей ASP.NET я расскажу только о страницах кэширования.

Предпосылки

Я предполагаю, что у вас есть базовые знания по разработке ASP.NET, включая навыки работы с данными, аутентификации на основе форм и работы с SQL Server или MSDE.

Начиная

Как я сказал во введении, почти все кэширование может быть выполнено с помощью одной строки кода, и эта строка:

<%@ OutputCache Duration="60" VaryByParam="None" %> 

Два свойства, определенные в теге, являются единственными необходимыми свойствами. Свойство Duration определяет в секундах длительность кэширования VaryByParam , а другой, VaryByParam , определяет ключ строки запроса (POST и GET), который автоматически удаляет страницу из кэша.

Вот и все! Страница кэшируется. Хотя приведенная выше строка является самым основным способом кэширования страниц, но даже это само по себе может начать повышать производительность вашего сайта.

Директива OutputCache имеет 3 других свойства, которые могут контролировать кэширование страницы:

  • Location
  • VaryByCustom
  • VaryByHeader

Каждый предлагает свой способ управления кэшированной страницей, что означает, что кэширование в ASP.NET очень гибкое!

Теперь давайте рассмотрим каждое свойство более подробно.

Duration

Как я уже сказал, это контролирует, как долго страница кэшируется, если она не удалена чем-то другим. Это свойство определяется в секундах и является обязательным. Если Duration пропущен, он вернет ошибку разбора (плохо).

Место расположения

Это свойство определяет, где страница должна быть кэширована. Существует 5 вариантов, каждый из которых можно найти в перечислении OutPutCacheLocation , которое является частью пространства имен System.Web.UI.

  1. Любые
    Это значение по умолчанию. По сути, он будет пытаться кэшировать его везде, где может (и под этим я подразумеваю одно из мест, перечисленных ниже, а не в вашем шкафу!).

  2. клиент
    Эта опция кэширует страницу в браузере клиента.

  3. вниз по течению
    Это кэширует страницу на любом устройстве с поддержкой HTTP 1.1, кроме исходного сервера. Обычно включает в себя прокси-сервер или клиент.

  4. сервер
    Кэширует страницу в памяти сервера.

  5. Никто
    Отключает кэширование вывода для запрошенной страницы, так же, как и пропущение тега.

VaryByParam

Это свойство позволяет вам определить, какие параметры, отправленные через POST или GET, удалят страницу из кэша. Это перезапишет свойство Duration и удалит страницу из кэша. Можно указать несколько значений, разделив их запятыми, а подстановочный знак ( * ) можно использовать для учета каждого варианта. Итак, пример тега с одним параметром:

 <%@ OutputCache Duration="30" VaryByParam="username" %>  <html>   <body>      Page was cache at: <strong><%=dateTime.Now.toString("G")%></strong>   </body>  </html> 

Каждый раз, когда отправляется другое имя пользователя, страница будет удалена из кэша. Попробуйте перейти на страницу без строки запроса, отметив время. Теперь добавьте? Username = bob в конце URL, и время изменится. Удалите строку запроса и вернитесь на страницу, она скажет то же время, что и в первый раз. И если вы подождете 30 секунд и обновите страницу, время будет другим!

VaryByCustom

Чтобы сделать объект Cache еще более гибким, Microsoft встроила возможность кэшировать страницу на основе строки, которая затем контролируется из реального кода приложения.

У него есть одно свойство «из коробки», Browser. Когда для VaryByCustom задано значение «Браузер», страница кэшируется каждый раз, когда другой браузерный агент и номер основной версии запрашивают страницу.

Так что, если у вас есть страница с этим вверху:

 <%@ OutputCache Duration="60" VaryByCustom="Browser" VaryByParam="none" %>  <html>   <body>      Page was cache at: <strong><%=dateTime.Now.toString("G")%></strong>   </body>  </html> 

время изменится, только когда другой браузер посетит страницу, или пройдет 60 секунд.

Вы также можете использовать пользовательский ключ и значение, переопределив HTTPApplication. Метод GetVaryByCustom в файле Global.asax.

Ok. Пришло время для той части, где мы должны думать …

Допустим, вы хотели кэшировать страницу, которая передала тех, кто зашел на ваш сайт. Давайте начнем с просмотра страницы, которую мы хотим кэшировать.

 <%@ Page Language="VB" Debug="true" %>  <%@ OutputCache Duration="300" Location="Server"  VaryByCustom="userLogged" VaryByParam="None" %>  <%@ import Namespace="System.Data" %>  <%@ import Namespace="System.Data.SQLClient" %>  <script runat="server">   Dim pageTimeDate As DateTime   Sub Page_Load(byVal obj As Object, byVal e As EventArgs)   userName.Text = Context.User.Identity.Name  End Sub   Sub logOut(ByVal obj As Object, ByVal e As EventArgs)   FormsAuthentication.SignOut()  End Sub   </script>  <html>   <head>   </head>   <body>   <form runat="server">      Page cached: <%=DateTime.Now.toString("G")%>      <br />      Logged in as:      <asp:Label id="userName" runat="server">Label</asp:Label>      <br />      <asp:Button id="Button1" onclick="logOut" runat="server"  Text="Log Out"></asp:Button>  </form>  </body>  </html> 

В первой строке мы устанавливаем для userLogged директивы OutputCache VaryByCustom userLogged . Используя подпрограмму Page_Load , мы отображаем текущего зарегистрированного пользователя (используя метку с именем username) и отображаем время. У нас также есть кнопка выхода из системы, так что мы можем легко войти как кто-то другой, чтобы протестировать скрипт.

Теперь рассмотрим скрипт для установки строки userLogged .

Как я уже говорил ранее, мы должны переопределить атрибут HTTPApplication.GetVaryByCutom , и мы можем сделать это в файле global.asax. Любой, кто много работал с ASP, знаком с файлом global.asa. Этот файл, который находится в корне вашего сайта, позволяет обрабатывать функции уровня приложения, которые должны запускаться при каждом запуске приложения или создании нового сеанса.

В ASP.NET файл global.asa был сохранен, но переименован в global.asax (и известен как файл приложения ASP.NET), но по сути он делает то же самое. Этот файл не является обязательным, и вы можете узнать больше о нем на сайте MSDN .

Теперь давайте перейдем к нашему коду …

В начале файла (файл global.asax), сразу после <script> , добавьте следующее:

 Public Overrides Function GetVaryByCustomString(ByVal  currentContext As HTTPContext, ByVal customArgs As String)  As String   Select CustomArgs      Case "userLogged"         Return "userLogged=" & Context.User.Identity.Name      Case Else         Return MyBase.GetVaryByCustomString(currentContext, customArgs)   End Select  End Function 

Сначала мы переопределяем (отсюда и ключевое слово Overrides ) метод GetVaryCustomString . Он имеет два параметра, первый из которых является HTTPContext (он содержит всю специфическую для HTTP информацию о запросе страницы), а другой — строку, представляющую значение атрибута VaryByCustom . Поскольку наш атрибут VaryByCustom — userLogged, он будет передан нашей функции в качестве параметра при запросе страницы. Мы используем оператор Select, чтобы проверить, что является параметром customtArgs, и поэтому мы можем легко добавлять другие значения, что означает, что мы можем кэшировать страницы различными способами.

Если строка была кэширована, это считается «попаданием», и страница обслуживается из кэша. Если строка не была кэширована, то это считается — как вы уже догадались — «промахом» и кэшируется.

И это все, что нужно сделать.

VaryByHeader

Каждый раз, когда вы запрашиваете веб-страницу, ваш браузер отправляет несколько заголовков HTTP. Вы можете настроить кэширование в соответствии с этими заголовками, например, вы можете кэшировать страницы в таких вещах, как Referer или Accept-Language. Вы можете найти список заголовков HTTP здесь . Вы бы использовали это так:

 <%@ OutputCache Duration="30" VaryByParam="none" VaryByHeader="Referer" %> 

Как и в случае с большей частью информации, которую мы уже рассмотрели, это простой атрибут, определенный в теге OutputCache! Этот простой пример будет кэшировать страницы в течение 30 секунд на основе Referer.

Заканчивать

Как мы только что видели, кэширование веб-страниц в ASP.NET удивительно просто, и выполняется с помощью простой строки. Благодаря этой возможности кэширования ASP.NET вы можете повысить производительность своего веб-приложения. Но помните: в этой статье мы рассмотрели лишь небольшую часть всего пространства имен кэширования! Попробуйте некоторые другие объекты, поэкспериментируйте, и ваши приложения будут работать быстрее, эффективнее и с меньшей нагрузкой на сервер!

Эта статья является частью SitePoint .NET Feature Guide — отличного ресурса для начинающих и опытных разработчиков .NET. Не пропустите!