One of the biggest bang for buck optimisations you can do to speed up a website is cache full html pages that would have otherwise been dynamically generated by a CMS. When a CMS generates a page it has to execute code, perform potentially dozens of database queries, perhaps consult external systems, before returning the result . These pages rarely change, if at all. Caching them and saving all the expensive processing required to build the page can result in big speed improvements, and dramatically reduce load on the origin server.
A few of our early adopters were websites built with the Magento 1 CMS. Unlike Magento 2, which is built with full page caching in mind, Magento 1 makes life difficult. The main difficulties are:
- The presence of the minicart on every page. As soon as an item is added to the cart the mini cart makes a page uncacheable.
- The use of form keys to prevent cross site scripting. Form keys are one off codes inserted into a form to prevent CSRF (Cross site request forgery) attacks. When the form is submitted the key is compared to the user's session on the server and if they're different the request is rejected.
When our first Magento 1 clients came on board we initially found we could get quick wins by serving cached pages until a product page was visited. The first visited product page drops a cookie called 'external_no_cache'. As the name suggests this says don't cache pages anymore! Once this cookie is dropped our full page cache is bypassed and requests are passed through to the origin server. Unlike some of our competitors bypass cache on cookie is available on all Peakhour plans.
Unfortunately this means that as soon as a product page is viewed by a visitor, then requests get passed through to the origin resulting in the old slow speeds. The initial goal of our Magento 1 plugin was to automate flushing of our edge cache when content is edited within the Magento admin. As we understood the platform better though we decided to extend our plugin to deal with the difficulties raised above.
To tackle the minicart issue we implemented a new AJAX call that returns the minicart content, total, and count. Once the call has been received the values are swapped into the empty minicart. The ajax is smart enough to know when it is necessary to fetch the content minimising calls to the origin.
To address the form key problem we replaced it with a strict referrer check. This checks the referrer header and makes sure it matches the store domain name. The referrer header is virtually never tampered for traffic over SSL and it is a recommended method of defense against CSRF attacks without the obvious drawbacks of form key implementations.
The plugin automatically set expires headers for cacheable pages minimising the need for configuration within the Peakhour admin.
A header is set listing all the products that appear on the page. These get stored as tags against the cached page, when a product is updated/deleted a flush by tag is issued targeting just the cached pages that the product appears on. This can substantially increase hit rate and reduce server load. Cache tags are available on all Peakour plans.
Viola, outside the checkout, customer area and wishlist functions, the rest of the site can be served from our cache with virtually no configuration. Our clients are very happy, and their customers are as well.
The plugin is now live in the magento store for anyone to download and start taking advantage of the improvements it can bring.