Professional Documents
Culture Documents
Magento is a well known open source e-Commerce platform. On other side it is also a complex
pieces of PHP software ever created. When it comes to complexity Magento has relatively low
performance when compared to custom made e-Commerce solutions. In order to improve this
situation, Magento uses the concept of Full Page Cache.
Basically Cache is a component that stores duplicate data that can served faster. Stored data is in
the form of values that have been processed earlier or duplicate of some values that are stored
elsewhere. If a user request some data and that data is already present in cache, this request can
be served by simply reading the cache, which in result is faster serving. Otherwise fetch from its
original storage location which in result is slow.
In general, caching improves response time and reduces load on server to increase page speed.
The pages which takes a second to load now loads in fraction of the time. Most techniques cache
static pages whose contents are rarely changes. However, most e-commerce sites serve dynamic
content, containing personalized information or data that changes more frequently. Caching
dynamic content requires more sophisticated caching techniques, such as those provided by Full
Page Cache (FPC) module for Magento Enterprise Edition.
Full page caching is a way for Magento to load content for a user without having to fully
initialize the application. This makes the entire website fast, but makes it less dynamic. Magento
has built-in ways to achieve a more dynamic page through a process called “hole-punching.”
Explanation:
Hole Punch Support In Full Page Cache, we know that the whole content of data stores in
cache. Most technique cache's the static content(that rarely changes) but what, if there is dynamic
content. At this point the concept of hole punching come into the picture.
Reduce Server Response Time After using page cache, reduces load on server which in return
increases the speed of page to load faster.
Multiple Currency Support Supports Multiple currency. Whether you have 1 currency or 100
currencies the page cache will not generate issues and user will always see the expected
currency.
Multiple Store / Language Support As we know Magento supports multiple store views,which
are typically used for different languages. Even after page cache there is no effect of cache on
languages.
Mobile Theme Support Mobile themes, theme overrides, and more are easily supported .
Simply input the required patterns you want to match on (example: iphone|blackberry|android)
and your cache will be set accordingly.
Cache Management in Magento Admin: We can enable or disable page cache in the admin
panel. Even we can clean cache storage through Magento admin.
Cache Lifetime: We can set lifetime of cache. If you set it to false, Zend cache will get default
value of 7200 seconds. If you want never expired cache set it to 9999999999, which is
Zend_Cache maximum value.
extractContent($content)
processContent($content)
processContainers($content)
applyWithoutApp($content)
applyInApp($content)
if (!$this->_designExceptionExistsInCache) {
//no design exception value - error
//must be at least empty value
return false;
}
if (!$content && $this->isAllowed()) {
$subprocessorClass = $this->getMetadata(\'cache_subprocessor\');
if (!$subprocessorClass) {
return $content;
}
/*
* @var Enterprise_PageCache_Model_Processor_Default
*/
$subprocessor = new $subprocessorClass;
$this->setSubprocessor($subprocessor);
$cacheId = $this->prepareCacheId($subprocessor-
>getPageIdWithoutApp($this));
$content = $cacheInstance->load($cacheId);
if ($content) {
if (function_exists(\'gzuncompress\')) {
$content = gzuncompress($content);
}
$content = $this->_processContent($content);
Enterprise_PageCache_Model_Cookie::registerViewedProducts($productId,
$countLimit);
}
}
}
return $content;
}
if ($sessionInfo) {
$sessionInfo = unserialize($sessionInfo);
foreach ($sessionInfo as $cookieName => $cookieInfo) {
if (isset($_COOKIE[$cookieName]) &&
isset($cookieInfo[\'lifetime\'])
&& isset($cookieInfo[\'path\']) &&
isset($cookieInfo[\'domain\'])
&& isset($cookieInfo[\'secure\']) &&
isset($cookieInfo[\'httponly\'])
) {
$lifeTime = (0 == $cookieInfo[\'lifetime\']) ? 0 : time()
+ $cookieInfo[\'lifetime\'];
setcookie($cookieName, $_COOKIE[$cookieName], $lifeTime,
$cookieInfo[\'path\'], $cookieInfo[\'domain\'],
$cookieInfo[\'secure\'], $cookieInfo[\'httponly\']
);
}
}
} else {
$isProcessed = false;
}
if
(isset($_COOKIE[Enterprise_PageCache_Model_Cookie::COOKIE_FORM_KEY])) {
$formKey =
$_COOKIE[Enterprise_PageCache_Model_Cookie::COOKIE_FORM_KEY];
} else {
$formKey = Enterprise_PageCache_Helper_Data::getRandomString(16);
Enterprise_PageCache_Model_Cookie::setFormKeyCookieValue($formKey);
}
Enterprise_PageCache_Helper_Form_Key::restoreFormKey($content,
$formKey);
/**
* restore session_id in content whether content is completely
processed or not
*/
$sidCookieName = $this->getMetadata(\'sid_cookie_name\');
$sidCookieValue = $sidCookieName && isset($_COOKIE[$sidCookieName]) ?
$_COOKIE[$sidCookieName] : \'\';
Enterprise_PageCache_Helper_Url::restoreSid($content,
$sidCookieValue);
if ($isProcessed) {
return $content;
} else {
Mage::register(\'cached_page_content\', $content);
Mage::register(\'cached_page_containers\', $containers);
Mage::app()->getRequest()
->setModuleName(\'pagecache\')
->setControllerName(\'request\')
->setActionName(\'process\')
->isStraight(true);
// restore original routing info
$routingInfo = array(
\'aliases\' => $this-
>getMetadata(\'routing_aliases\'),
\'requested_route\' => $this-
>getMetadata(\'routing_requested_route\'),
\'requested_controller\' => $this-
>getMetadata(\'routing_requested_controller\'),
\'requested_action\' => $this-
>getMetadata(\'routing_requested_action\')
);
Mage::app()->getRequest()->setRoutingInfo($routingInfo);
return false;
}
}
Enterprise_PageCache_Model_Container_Placeholder::HTML_NAME_PATTERN,
$content, $placeholders, PREG_PATTERN_ORDER
);
$placeholders = array_unique($placeholders[1]);
$containers = array();
foreach ($placeholders as $definition) {
$placeholder = new
Enterprise_PageCache_Model_Container_Placeholder($definition);
$container = $placeholder->getContainerClass();
if (!$container) {
continue;
}
if
(Mage::getStoreConfig(Enterprise_PageCache_Model_Processor::XML_PATH_CACHE_DEB
UG)) {
$debugBlock = new Enterprise_PageCache_Block_Debug();
$debugBlock->setDynamicBlockContent($blockContent);
$debugBlock->setTags($this->_getPlaceHolderBlock()-
>getCacheTags());
$debugBlock->setType($this->_placeholder->getName());
$this->_applyToContent($content, $debugBlock->toHtml());
} else {
$this->_applyToContent($content, $blockContent);
}
$subprocessor = $this->_processor->getSubprocessor();
if ($subprocessor) {
$contentWithoutNestedBlocks = $subprocessor-
>replaceContentToPlaceholderReplacer($blockContent);
$this->saveCache($contentWithoutNestedBlocks);
}
return true;
}
$block = $this->_loadCache($cacheId);
if ($block === false) {
return false;
}
$block = Enterprise_PageCache_Helper_Url::replaceUenc($block);
$this->_applyToContent($content, $block);
return true;
}
1] To refresh Full Page Cache: Sometimes full page cache appears in yellow color that is
“Invalidate” so all time we have to refresh it:
This issue is found on many sites that the currency not switch. When currency switched,
doesn’t refreshed cache. Users does not see the correct currency on site. Sometimes
product price is not change when switching currency as per the currency. It always
display same currency on site which is saved in full page cache.
The Cart Sidebar won't get updated when product is added to cart or it shows different
cart quantity on Homepage and different cart quantity on another pages. It does not
display new or updated cart quantity . Always get quantity of product from cache which
is not hole-punch.
Issue with Welcome message having random names when Logged in. It shows different
online customer name randomly on different page.
Before few days client found an issue that the Cart Sidebar won't get updated when product is
added to cart or it shows different cart quantity on Homepage and different cart quantity on
another pages. It does not display new or updated cart quantity.
In cartheader.phtml
http://stackoverflow.com/questions/9120413/how-do-i-include-a-dynamic-block-in-the-
product-page-with-full-page-caching-turn
http://magento.stackexchange.com/questions/8481/how-to-hole-punch-a-child-block-
added-inside-catalog-product-list-block
http://www.pixafy.com/blog/2013/03/overcoming-magentos-full-page-cache-through-
hole-punching/
http://invisiblezero.net/magento-ee-punch-hole-in-full-page-cache/
http://www.magentothemess.com/archives/1739
http://www.developers-paradise.com/wp-content/uploads/2014/03/NRG_-
MDP_Presentation_Max_Gubar_Ibiza_2012.pdf
http://www.kingletas.com/2012/09/how-does-magento-full-page-cache-works.html
http://stackoverflow.com/questions/8126548/trying-get-dynamic-content-hole-punched-
through-magentos-full-page-cache
http://magento.stackexchange.com/questions/13957/full-page-cache-on-ce-1-8-an-fpc-
magento-module-varnish-both
What is the difference between cache and Full Page cache in Magento
Cache:
When a user visiting a website page for the first time, Magento generate and deliver this page to
the visitor and automatically save a copy of it to the cache. Then all those pages get stored in a
cache. Each time when user request arrives, the system does not request Magento to generate a
page, but returns the copy of the page from cache. Neither cache will connect to the Magento
database or load any Magento files ,it can load the request from cache.
we need some conditional approach because constructor approach isn’t enough in most
scenarios.
Full page caching is a way for Magento to load content for a user without having to fully
initialize the application. This makes the entire website fast, but makes it less dynamic. Magento
has built-in ways to achieve a more dynamic page through a process called “hole-punching”.
With FPC complete page is cached and hole punching(container) system where by containers are
replaced with complete html if needed.
Hole-Punching
The page is composed of block and template files. To keep this dynamic relationship active with
FPC on we are given the ability to surround our block and template files with something called a
placeholder, or container.
To retrieve content, containers have two major functions that are important to us:
applyInApp($content) and applyWithoutApp($content).
Depending on the page, content, and cache lifetimes, Magento will handle each request slightly
different.
1. Page is in cache with no dynamic blocks: Magento did a minimal amount of work to achieve
a page load
2. Page is in cache, dynamic blocks are cached: Similar to State 1, Magento gets a request to
load a webpage and finds the page is cached. Magento then comes across a container for a
dynamic block. From here it determines if the block is cached or not and if so, will proceed to fill
the container with the cached block using applyWithoutApp($content) so we have another full
page load with very minimal overhead.
3. Page is in cache, dynamic blocks are not cached: In state 2 was unable to fetch and deliver
the dynamic block content, so the block content needs to be generated, even though the rest of
the page has been found in the FPC. For this purpose the FPC module sets the request to
pagecache/request/process, and the regular Magento application initialization and routing is
followed. The method fetches the previously instantiated container class for the dynamic block,
and calls applyInApp($content) on it.
4. Page is not in cache: In this state Magento did not find the requested page in the cache, so the
page must be processed as usual.