Фрагментарное кеширование

HTML и CSSXSLTJavaScriptИзображенияСофтEtc
Андрей Шитов

23 ноября 2005


Не обязательно кешировать веб-страницу целиком: достаточно положить в кеш отдельную ее часть. Часть, которая требует повышенной нагрузки на сервер, либо часть, которая изменяется заведомо редко. Никто не мешает положить в кеш сразу несколько частей одной и той же страницы.

Техническое
отступление

Обычную страницу, созданную с помощью технологии Microsoft ASP.NET, очень просто закешировать на сервере — достаточно директивы @OutputCache, имеющей несколько параметров, позволяющих создавать разные версии кеша. В то же время, любая ASP.NET-страница может включать в себя нестандартные пользовательские элементы управления — «серверные контролы» (server controls). Стандартный пример пользовательского контрола — форма авторизации (до тех пор, пока не появился ASP.NET 2.0, ее приходилось писать вручную). Такие элементы по сути являются ASP.NET-страницами, обладающие теми же возможностями кеширования.

Например, программист создает страницу, содержащую два серверных контрола — форму входа и список новостей на сайте — и дает команду кешировать новости до тех пор, пока не появятся новые. Пользователь же получит страницу из совмещенных вместе кусочков.

См. также статью Caching Portions of an ASP.NET Page на MSDN.


Пример из реальной жизни
Посмотрите на первую страницу словаря сокращений русского языка. На ней есть несколько фрагментов, которые не являются статичными.

В двух блоках (с номерами 1 и 4) отображаются случайные примеры из словаря. При каждой перезагрузке страницы они изменяются (причем независимо друг от друга).

Другие два фрагмента показывают текущее состояние базы данных. В блоке под номером 2 видны размер словаря и число сокращений, добавленных посетителями, но еще не проверенных редакторами. В самом крупном блоке (3) показаны последние одобренные сокращения и их расшифровка.

Дальше не интересно: пятый блок — это счетчик посещений, а вся остальная часть страницы полностью статична (разве что кроме года в копирайте).

Только два из пяти показанных фрагментов требуют свежих данных из базы. И только они требуют подключения к ней. Заведомо известно, что обновление этих частей страницы потребуется гораздо реже, чем страницу будут запрашивать посетители сайта. Поэтому вместо того, чтобы каждый раз делать SQL-запросы, сервер просто кеширует результат и сохраняет его в файле:

01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
11 
12 
13 
14 
15 
<list>
    <item>
        <sokr>КЭЗ</sokr>
        <value>канифольно-экстракционный завод</value>
        <comment>лесное хозяйство<br />
        например: ОАО &laquo;Лесосибирский КЭЗ&raquo;</comment>
    </item>
    . . .
    <item>
        <sokr>ВНИИСХРАЭ</sokr>
        <value>Всероссийский научно-исследовательский институт
        сельскохозяйственной радиологии и&nbsp;агроэкологии</value>
        <site href="http://www.admoblkaluga.ru/New/SCIENCE/VNIISHRAE/"/>
    </item>
</list>

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

А надо ли?

Иногда кешировать вообще ничего не нужно, даже если интуитивно хочется. Например, когда HTML-код формируют с помощью XSLT, хочется раз и навсегда скомпилировать XSLT-файл и положить его в кеш. Но если взять библиотеку libxslt, то окажется, что сохранить пригодную для повторного использования копию труднее и медленнее, чем просто «распарсить» код заново.

См. обсуждения в архиве списка рассылки xslt@gnome.org:

Libxslt: xsl:include/import cache? — 4 декабря 2001

Deep-copy of xsltStylesheetPtr? — 18 сентября 2004


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

Кстати, RSS «Техногрета» тоже кешируется.