Magento 2 comes stock with a full page caching feature. However, it's not clear how the framework determines which URL end-points need to be cached. For example, if I create a simple controller that acts as a JSON endpoint
$data = ...;
$result = $this->resultJsonFactory->create();
return $result->setData($data);
The system seems smart enough to know not to cache this.
curl -I 'http://magento2.example.com/my/custom/endpoint'
//...
X-Magento-Cache-Debug: MISS
I've been able to track the built in caching functionality to this method (used by the built-in plugin)
#File: lib/internal/Magento/Framework/App/PageCache/Kernel.php
public function process(\Magento\Framework\App\Response\Http $response)
{
if (preg_match('/public.*s-maxage=(\d+)/', $response->getHeader('Cache-Control')->getFieldValue(), $matches)) {
$maxAge = $matches[1];
$response->setNoCacheHeaders();
if ($response->getHttpResponseCode() == 200 && ($this->request->isGet() || $this->request->isHead())) {
$tagsHeader = $response->getHeader('X-Magento-Tags');
$tags = $tagsHeader ? explode(',', $tagsHeader->getFieldValue()) : [];
$response->clearHeader('Set-Cookie');
$response->clearHeader('X-Magento-Tags');
if (!headers_sent()) {
header_remove('Set-Cookie');
}
$this->cache->save(serialize($response), $this->identifier->getValue(), $tags, $maxAge);
}
}
}
Which seems to examine the response object, and only cache requests if they're a HTTP 200
, either a GET
or HEAD
request. It also uses the Max-Age Cache-Control
header to ensure values are saved in the cache for an appropriate amount of time.
So, it's clear from this code that something instructs the system (i.e. sets cache headers on the response) to cache the request. What's not clear is where this happens during Magento's request flow, and which requests gets full page caching and which do not.
Best Answer
Response is marked as cacheable in
\Magento\PageCache\Model\Layout\LayoutPlugin::afterGenerateXml
only in case if there are no blocks in the layout of current page marked withcacheable="false"
attribute, like this:By default all CMS, product and category pages should be cacheable, their layouts were refactored so as not to contain non-cacheable blocks.
Also keep in mind, there is a bug related to usage of
cacheable="false"
on product pages described here.