Организация "кусочкового" кеширование HTML
Навеяно парой статей на Хабре, и тем, что вчера сделал cache тег для Macro.
Зачем?
Хочется убить двух зайцев: избавиться от запросов за редко изменяемыми данными, и их отрисовки. Вообще это смахивает на попытку минимальным количеством движений сделать глобальное счастье. Можно потом перед другими фрэймворками меряться, ага.
На самом деле задача избавиться от отрисовки куска страницы вообще какая-то странная, если мы используем быстрый шаблонизатор. Application-сервера, при нормальной арихитектуре, масштабируются легко и непринужденно, а APC, сам закэширует скомпилированный шаблон, если он компилируется в РНР-код, как это сделано в Smarty, Macro и многих других.
С другой стороны, если есть простой способ закэшировать, то почему бы и нет.
Откуда данные, и как заставить протухнуть кэш.
Данные в шаблоне могут получаться двумя способами. Первый и традиционный это push-подход, когда контроллер заполняет какой-то data-transfer-object, или в сам шаблон. Такой подход используется чаще всего, ибо это “тру MVC”!
Второй подход – pull. При pull подходе в шаблоне расставляются инструкции по получению данных, в обход контроллера, напрямую от моделей, сервисов и прочих провайдеров данных. Этот способ позволяет избавиться от повторяющихся set’ов в контроллере, но не позволяет ограничить, из контроллера, их получение, и усложняет поддержку шаблонов, ибо иногда трудно понять откуда получены данные.
Теперь об определении развалидации кэша. Тут тоже два основных подхода. Первый – ttl(time-to-live – время жизни). Мы определяем, что список новостей, например, валиден в течении 15 минут. Основной плюс – мы уверены, что за данными скрипт будет обращаться не чаще чем раз в 15 минут, и зная частоту обращений можем точно расчитать эффективность такого кеша. Второй плюс – простота реализации. Главный же минус в том, что наш список на самом деле может измениться через секунду после построения кэша, а пользователь увидит изменения только через 15 минут.
Второй вариант сброса кэша – по действию. Например, тот контроллер(экшн), который отвечает за публикацию новостей, сам убивает кеш, и формирует новый (тут тоже много разных камней, типа lost updates, и прочих порождений многопоточности, но все они решаемы). Плюс – кэш всегда валиден. Первый минус это сложность реализации (нам нужно добавлять код для работы с кэшем во все места, где идет работа с данными кэша – публикация новостей, их удаление, и т.д.). Второй минус в том, что эффективность такого кэша сильно зависит от частоты изменения данных.
А теперь тоже самое, но в свете кэширования частей страницы.
Push me. And then just touch me…
Кэшировать части страницы, при push-данных хуже, чем кэшировать эти самые данные. Почему? Потому что мы “загадим” кодом работы с кэшем и шаблон, и контроллер, а из плюсов только экономия на отрисовке.
Pull-данные и развалидация по действию
Что мы получаем? Логика работы с кешем в шаблоне и тех контроллерах, которые отвечают за действия. Опять не тру, и лучше опять кэшировать данные, через какой-нибудь LastNewsService.
Pull-данные и ttl
Вот то ради чего собственно и делаются теги cache, блоки django, компоненты и т.д. Вся логика только в шаблоне (или настройках компонента). Красотища!
Вывод:
Кэширование части HTML имеет смысл только для pull данных с устареванием по времени. Во всех остальных случаях его плюсы, по сравнению с кэшированием данных, сводятся к экономии работы шаблонизатора.
SSI вкусен, но очень тормозной…
А вам не кажется, что SSI в этом случае выглядит предпочтительнее, за счет своей асинхронности и возможности кэширования по отдельности?
Ну я как бэ о языковых средствах писал. В остальном да – SSI вкусен.