Обзор
Чтобы ответить, мне нужно сначала немного объяснить.Процесс Magento FPC знает четыре состояния.
- Страница в кеше, без динамических блоков
- Страница в кеше, динамические блоки кэшированы
- Страница в кеше, динамические блоки не кэшированы
- Страницане в кеше
Состояния 1 и 2 обрабатываются без полной инициализации приложения Magento.Состояния 3 и 4 требуют инициализации приложения и обработки маршрутизации.По этой причине стремитесь обслуживать запросы из состояний 1 и 2, если это возможно, в противном случае вы теряете большую часть возможных улучшений FPC.
Состояние 1
Состояние 1 является скучным изс точки зрения разработчика, ничего не делать, поэтому давайте перейдем к ...
Состояние 2
В состоянии 2 страница содержит динамические блоки. В данный момент Magento не полностью инициализирован .
Процессор FPC загружает кэшированную страницу и находит в ней заполнитель для динамического блока.
Анализируя заполнитель, процессор можетопределить класс контейнера для динамического блока, создать его экземпляр и вызвать applyWithoutApp($content)
для него.(Название метода относится к тому факту, что приложение Magento до сих пор не инициализировано).Затем контейнер пытается загрузить содержимое динамического блока из кеша блока, используя ключ кеша, возвращаемый методом $this->_getCacheId()
.
Если возвращается ключ кеша и может быть загружена запись в кеш, класс контейнера заменяет заполнительв $content
с выводом кэшированного блока и выполнением FPC.
Пока не было получено слишком много служебных данных.
Состояние 3
Так что applyWithoutApp($content)
в состоянии 2 былоневозможно получить и доставить содержимое динамического блока, поэтому необходимо создать содержимое блока, даже если остальная часть страницы найдена в FPC.
Для этой цели модуль FPC устанавливает запрос на pagecache/request/process
,и за ним следует обычная инициализация и маршрутизация приложения Magento.
Это означает, что при состоянии 2 создается намного больше накладных расходов, чем при обычной загрузке страницы без FPC, потому что, например, перезапись URL
Наконец, передний контроллер и стандартный маршрутизатор делегируют запрос методу RequestController::processAction()
d.
Метод извлекает ранее созданный экземпляр класса контейнера для динамического блока и вызывает для него applyInApp($content)
.
Этот метод запускает $this->_renderBlock()
, чтобы создать экземпляр класса реального блока и вернуть его выходные данные.Вы уже реализовали этот метод в соответствии с вашим вопросом.FPC теперь может заменить заполнитель содержимым блока и доставить страницу.
Следует помнить, что - это не обычный запрос страницы сведений о продукте, поэтому, например, Mage::registry('current_product')
неимеется в наличии!В зависимости от реализации вашего блока это может повлиять на кэширование на уровне блоков или генерацию содержимого динамического блока.Я подозреваю, что это может быть из-за вашей проблемы, но я найду возможный обходной путь чуть ниже.
Состояние 4
В этом состоянии FPC не нашел запись кэша для запрошенной страницы, поэтому Magento генерирует страницу как обычно, например, вывод сведений о продукте создается с помощью Mage_Catalog_ProductController::viewAction()
.
Все блоки, настроенные как динамические, согласно cache.xml
, обернуты в теги-заполнители.
Теги-заполнители содержат аргументы, которые позже передаются объекту-контейнеру для шагов 2 и 3Единственные аргументы, которые всегда установлены, - это контейнер и имена классов блоков.Но почти всегда задаются cache_id
и template
.
В классе контейнера к этим значениям можно получить доступ с помощью $this->_placeholder->getAttribute('cache_id')
(как вы это делали в методе _getCacheId () вашего контейнера).
Даже если вы замаскировали большую часть этого длинного ответа, это может быть вам интересно. Если вам нужны дополнительные значения для генерации идентификатора кэша блоков или вывода блока (например, идентификатора продукта или идентификатора клиента), вы можете установить их в качестве аргументов для заполнителя .
Для этого вам нужно установить их в массиве, возвращаемом методом block getCacheKeyInfo()
со строкой в качестве ключа массива . Если вы используете числовой индекс массива, они не будут установлены в качестве аргументов для заполнителя.
public function getCacheKeyInfo() {
$info = parent::getCacheKeyInfo();
$info['current_product_id'] = Mage::registry('current_product')->getId();
$info['customer_id'] = Mage::getSingleton('customer/session')->getCustomerId();
return $info;
}
Эти значения теперь доступны в классе контейнера, используя $this->_placeholder->getAttribute('current_product_id')
.
Заключение
Вы, вероятно, не хотите переопределять _saveCache()
в своем классе контейнера для возврата false
. Вместо этого включите идентификатор клиента и идентификатор продукта в строку, возвращаемую _getCacheId()
. Таким образом, каждый клиент получает свою собственную запись в кеш. Некоторые накладные расходы будут уменьшены, поскольку applyWithoutApp()
может сохранять и загружать динамический блок из кэша (если страница просматривается дважды одним и тем же пользователем).
В _renderBlock()
установите дополнительные значения, которые вам нужны, чтобы блок мог генерировать на нем свое содержимое, например,
$block->setProductId($this->_placeholder->getAttribute('current_product_id'));
На стороне блока, включая идентификатор продукта и идентификатор клиента в массиве данных кэша, будет гарантировано, что каждый клиент получит правильный вывод для запрошенной страницы, даже когда блок кэшируется.
Я не могу знать наверняка, (вы не предоставили код блока), но я подозреваю, что используемый вами идентификатор кэша не содержит всех аргументов, необходимых для однозначного сопоставления записи кэша для блока. правильный продукт.
Используя эти шаги и зная, как передавать аргументы в контейнер динамических блоков, можно сохранить большую часть выигрыша в производительности FPC даже при создании пользовательских динамических блоков. Я надеюсь, что этой информации достаточно для того, чтобы вы смогли отследить описанную проблему и исправить ее.