Category:
Services
Author: Hellmann eCommerce
Fast Magento

Performance improvement of a Magento shop

In one second. A hummingbird makes 90 wing beats. In one second. An airliner covers a distance of 244 meters. In one second. Approximately 7% of the users of online shops give up annoyed because their requested page was not displayed. Two seconds, three seconds, four seconds. After that elapsed time, there are already 25% or more disappointed users, depending on which statistic you believe...

Google, which has been rumored for a while to use the loading times of a web-page as a secret ranking factor in its search engine, gives yet another reason why online traders should keep an eye on the response times of their respective shops, and optimize as much as possible. We will deal, in the first part of this two-part article, with the server side, and clone a Magento instance on two sample configurations. We will then have these configurations gradually optimized, and then have them compete against one another.

 

What did we test?

The possibilities of optimization are varied, and certainly everybody has his or her own unique recipe or favorite setup on which they rely on. Therefore, for this test series, we focused on the effect of various levels of caching and the increase in speed that can be achieved through the use of an alternative PHP engine called HHVM.

Our test setup:

   Setup "PHP5"  Setup "HHVM"
CPU DualCore@1.8 GHz
RAM 18 GB
OS CentOS 6.6
Webserver Apache 2.2
DB MySQL 5.5.42
PHP  PHP 5.4.37  HHVM 3.5.0 via FastCGI

 

How did we test?

All of the tests were conducted on the server (localhost) itself to exclude the Internet as a component that could potentially falsely alter results. The test tools were fed with a URL list of typical store pages (home, main category page, product list, product detail page, and account login), and we called up the URLs one after another on both setups.

We used the following metrics as indicators to assess the performance:

1. Page views per second (hits)

siege –b –c1 –t1M <url> 

(Benchmark mode with one user at a time;
Benchmark and load tool, http://www.joedog.org/siege-home)

2. Server response time (TTFB, time to first byte)

curl -o /dev/null -w "%{time_starttransfer} secs\n" <url>

(Command lines program to download files from a URL)

The first goal in the analysis and optimization of the store performance should therefore be the lowest possible TTFB value (<150ms). This represents the initial waiting time after calling up a URL before the browser can start downloading and analyzing the HTML content. If network-related factors that may increase waiting times (DNS, its own connection to the server and geographical distance) can be excluded, a high TTFB value may be indicative of performance problems on the server itself. This is where we want to start.

TTFB-Analyse

Figure 1: TTFB analysis with the Chrome Developer Toolbar

 

HipHop Virtual Machine

Unlike other programming languages such as C ++ or Java, PHP source code will be interpreted and executed on every page load (if no other optimization measures are in effect). HipHop Virtual Machine, developed by Facebook, or HHVM in short, takes a very different approach. Based on a just-in-time (JIT) compiler, it translates the PHP source code into an intermediate stage, the so-called HipHop bytecode, which in turn is dynamically translated by HHVM into quickly executable machine code. These optimizations must be only done once, as the repeated executions save a lot of computation time, and bring a significant jump in performance.

Caches deaktiviert

Figure 2: Response times with disabled Magento cache (less is better)

The first test run with a deactivated Magento cache is therefore intended to show the changes that take place when HHVM is in effect, while virtually the entire page content must be newly created on every refresh. In the worst case shown here, the user must wait more than a second before even the downloading of the webpage, and its embedded images and scripts, etc. can be started. Fortunately, it is not normal to run a shop with deactivated Magento caches.

 

Caching

A beautiful german proverb says, "What we forget to have in our heads, we have to carry with our legs" Applied to this case, it could perhaps be read as: "If you need anything more than once, get it all at the same time instead of going back each time, and having to pick it up again and again.”
A cache is therefore nothing more than a repository of the result of time-consuming work that’s already been done which can be accessed quickly.
But caches are not a precise remedy, and should always be seen as the last step in an optimization process. Preceding the implementation of a cache, you should always solve general performance problems as server configuration issues, a slow database system, low memory, and slow CPUs/disks.
Magento brings a colorful bouquet of caching options for configuration, language files, HTML block content and more. Enabled on both systems, the webpages with Magneto caches show a significant performance increase compared to webpages without caches.

Nur Magentocache

Figure 3: Response times with activated Magento cache (less is better)

Administrators could already tolerate these values under normal circumstances. However, the rather large delay would tarnish user satisfaction when loading the product lists. This could lead to very high dropout rates, so we have to put it up a notch.

 

Curtain up for Varnish

The Web accelerator Varnish is used by many well-known sites, including the already mentioned Facebook. Some others include Twitter, the New York Times and Vimeo. Varnish is normally used as a reverse proxy in front of the web server that receives incoming requests from the Internet. If the requested page is known to Varnish (if it already has a current version of the HTML content of the page) then it will be delivered directly. Otherwise, a query to the Web server (which has no direct connection to the internet) is made in which case the response times were very similar to those of the test run last shown. This works well for completely static pages without dynamic content. Often, however, adding an item to your cart and therefore changing the number of total items displayed should result in the correct amounts being shown after you refresh the page. So we have the choice to continue with the delivery of un-cached dynamic pages (which would affect 90% of the shop pages) or a shop layout with very few dynamic elements. Fortunately, Varnish offers the possibility to isolate elements which should be exempt from caching, making single requests for each of them to the web server while it takes the rest of the page from its cache and combines it with these selected elements to deliver the final page content. This is faster than regenerating the entire page as a whole. The magic word is ESI (Edge Side Includes) which is an XML-compliant markup language, that helps define these dynamic blocks so that Varnish can recognize them and handle them properly.

Example:

<esi:include src="http://shop.com/esi/block/id/quickbasket" />

When delivering a page, Varnish notices such an ESI-block, requests the embedded URL from the web server, and then adds the answer into the overall construct. Ideally, this additional request is much faster than the refreshing of the entire page and so it delivers a noticeable performance boost without sacrificing the dynamic content. Too many ESI block requests, however, could cancel out this advantage so be careful to not overdo it. Another alternative is to let your browser handle these additional request by using the Ajax technique. Here, the requested dynamic contents update themselves after the page has loaded, which is rarely bothersome.
The free Magento module Turpentine offers an optimized Varnish configuration as well as functionality, which tags these dynamic content blocks automatically to make them ESI integratable.

Varnish aktiviert

Figure 4: Varnish accelerates the delivery of pages immensely (less is better)

The result speaks for itself. In spite of dynamic content on the page and the associated queries to the web server, response times are negligible. However, it must be remembered that we have measured directly on the server. Via the Internet, we would observe TTFB values of around 50ms. The relatively high values for the account pages stem from the fact that these contents are generally not cached. Under certain circumstances, therefore, the response time by Varnish may be even slightly larger than directly to the web server.

 

Conclusion and outlook

These results show clearly how much the use of inserting clever caching mechanisms and the HHVM pays off. It should be noted that the setup might face different challenges when confronted with a large number of simultaneous page requests. If this happens, it will have to meet other requirements and perhaps even a change to a different web server like Nginx or the integration of a caching backend such as Redis might be useful. In any case, an administrator should always know the maximum capacity of their store which is determined by appropriate load tests so that he or she can react to rising traffic. For a user who has canceled a purchase due to poor performance may never come back.

Zusammenfassung

Figure 5: Average values without account pages (TTFB: less is better, Transactions: more is better)