Full Page Cache in Magento 2.0
In Magento 2.0, full page cache is built-in for both the Magento 2.0 Community platform, as well as the Magento 2.0 Enterprise system.
I can’t emphasize how amazing this feature is to have for an eCommerce store.
Full page caching essentially turns your database-driven Magento 2.0 store into a site with the speed of an old-fashioned, static HTML site. What this means is that when an end user comes to your site, there’s no database calls and very few file system calls to return (or “serve”) that page to the end user.
Think back to a vintage 1994 website: You have an index.html page that contains all of the content, and perhaps an image or two. A page like this loads really quickly, but is next to impossible to keep updated with inventory levels, current pricing and other fresh content.
A modern server can serve literally tens of thousands of cached, static HTML pages without breaking much of a sweat or having the server’s processor power spike. But a database-driven site might need 125 different database calls and file system lookups to build a single page for a single user.
Meaning that a normal Magento category page or product page can take 5-10 seconds to load on a server that has all the caching turned off.
But with full page caching turned on (like the one in the new Magento 2.0 system), this drops to about 1 or 1.5 seconds.
In Magento 2.0, full page caching files are stored in the /var/page_cache/ directory.
These files are built by Magento and updated as a page is created, a product is added or edited, or category information is built.
Magento will cache:
- CMS (Content Management Pages)
- Category Pages
- Product Pages
- Error Message pages
These pages are never cached using full page cache:
- Account pages (login, create account, address book, wishlist)
- Cart page
- Checkout page
- Checkout success page
Magento further creates a separate version of each page based on:
- Customer Group
- Website or Store View
- Language (if multiple are turned on)
(Note: if you’re trying to use Varnish for page caching, it’s important to make sure that you don’t cache these pages, or all of your users will see each other’s cart contents!)
Hole Punching on Magento 2.0:
However, on a block level, you can have specific areas on a page that do not use full page cache. For example, the small persistent shopping cart at the top of a page that indicates how many products you have in your cart (i.e. 3 products) is not something that should be cached. This can be excluded from the cache on a per block or extension level. This is known as hole-punching.
To understand hole punching for Magento 2.0 Community and Enterprise, think of a Web page as a sheet of paper. If you want to have an area of the page that isn’t cached, think about using a big metal hole puncher to cut right through it. And then the rest of the page is cached and loads quickly.
Public vs. Private Cache Content in Magento 2.0:
Public content: There are some things that are great to cache for all people (i.e. a CMS page or product page). This doesn’t change very often, so it can be public.
Private Content: If you want to have the site personalized by displaying someone’s name at the top of a page (i.e. “Welcome, Jeff!”), then it will slow down the page load time if you have to have the system fetch this information each and every time.
In Magento 2.0, private information can be cached by the web browser (i.e. Chrome or Safari), so that the system doesn’t have to reach out each and every page for this information. It can be stored locally, so that page load times are as fast as possible.
The reality is that there is very little actual documentation right now for how full page cache works in Magento 2.0 (as of July 2015). Alan Kant has a bit of high-level information about caching; I wanted to delve into the actual files and how it works.
The documentation on Magento 2.0 right now still refers to using the local.xml file for configuration; this has been replaced in the /app/etc/ directory with the env.php file.
From what I can tell right now, when an end user goes to the site to request a page, the Magento system will check to see:
- If that page is available as a cached page.
- If the cached page is still valid (you can set an expiration date on the page)
Each page that is cached has a unique ID that Magento uses to retrieve the HTML page contents.
For full page caching, the system is looking at this path to retrieve the page information:
The actual file path goes to a php file here:
Then, the Magento 2.0 system will look in the /var/ directory in the /page_cache/ sub-directory.
This directory (/var/page_cache/) is then divided into different folders that make it easier for Magento to find the actual files it needs.
These folders are in the /var/page_cache/ directory:
mage–0 mage–2 mage–4 mage–6 mage–8 mage–a mage–c mage–e mage-tags
mage–1 mage–3 mage–5 mage–7 mage–9 mage–b mage–d mage–f
The actual full page cache file is then in one of these subdirectories.
All of this is automagically generated by Magento when it builds out a page.
Here’s an example of an actual page cache file:
The name of the file is:
The file includes:
Hash: This is a unique identifier so that the system can find this page quickly and easily
Mtime: This is a Unix date stamp of when this was added into the cache. In this case, this file’s date is: 1437651736. If you translate this into a human-readable date, it’s Thu, 23 Jul 2015 11:42:16 GMT
Expire: This is another Unix date stamp; in this case it is the time when this cached page is no longer valid (and tells the system to rebuild it). In this case, expire is set to: 1437738136. This translates to: Fri, 24 Jul 2015 11:42:16 GMT.
(The Unix date date stamp is based on the number of seconds that have occurred since January 1, 1970.)
Tags: The file also contains many different tags that associates this page to different categories in the Magento site. This product belongs to several different category tags in the system.
URL for Interceptor / HTTP Cache Header information: The top contents of the file also reference the path or location where Magento handles the content interceptor. This is used to figure out if a page is in cache, or if it is invalid and needs to be recreated. It also helps generate the HTTP cache header, which will tell an end user’s browser that this page is okay to be cached (i.e. if they come back to the page 15 minutes later), or if that cache is no longer valid and needs to be downloaded again.
Here’s the top contents of the file:
<meta http-equiv=”Content-Type” content=”text/html; charset=utf-8″/>
<meta name=”description” content=”Default Description”/>
<meta name=”keywords” content=”Magento, Varien, E-commerce”/>
<meta name=”robots” content=”INDEX,FOLLOW”/>
<meta http-equiv=”X-UA-Compatible” content=”IE=edge,chrome=1″/>
<meta name=”viewport” content=”width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=no”/>
<title>Pants – Bottoms – Men</title>
<link rel=”stylesheet” type=”text/css” media=”all” href=”http://magento2.6cp.com/pub/static/frontend/Magento/luma/en_US/mage/calendar.css” />
(File continues with normal HTML.)
Here’s a screenshot of the file; this is using the sample Magento 2.0 data so that there are products and other information available for testing: