Optimizing Prestashop is something I spend a lot of time on, in fact it is something that I specialize in. Everyone has their own opinions of what you can do to make your Prestashop store the fastest. I have spent weeks testing different set ups and I can tell you without a doubt what you can do to make your Prestashop store the fastest it can be.
Get a VPS account
This is the foundation of a fast site. Shared hosting will not let you do the things described in this article, so you need to have a good VPS account. I always suggest WebHostingBuzz for hosting, they have fast servers and provide excellent support. A couple notes to hosting that I would like to mention. I do not recommend using hosts that are “cloud hosts” or instance based hosting. The reason being Prestashop requires processing power and memory. These type of hosts seem to allocate memory, but not processing power. I always recommend people to select a host that is transparent with how much processing power you have allocated to your account. Terms like 8x or 16x processing power mean absolutely nothing to me. What are they 8x or 16x of? I prefer knowing what resources I actually have at my disposal. With WebHostingBuzz I know that I am actually getting processor cores with a VPS account and I know what the processors are.
Another suggestion is to stay away from using SSD drives for doing these things I am going to mention, they are a waste of money and will actually slow some of the more important database queries down. You will have better performance at a host that has their drives set up in a raid 10 configuration. Trust me on this one, I will explain it more in depth later.
The base server setup
For your base server setup I recommend using Apache 2.2, PHP 5.4, and running PHP in Fastcgi. In WHM you should be able to build this set up with EasyApache. I also recommend installing mod_pagespeed as well.
Once you have these installed on your server, you will need to install Pecl so your WHM can access the Pecl extension library. The main extension that you want to install with Pecl is APC.
Zend optimizer has replaced APC in PHP 5.5 and also APC does not work in PHP 5.5. Don’t worry though, that is why we installed PHP 5.4, from my tests with Prestashop APC is a far superior Opcache than Zend or as it is called in PHP 5.5 opcache is.
What an Opcode cache does is pretty simple. When a user access your site, the PHP files are retrieved from disk, then compiled to Opcode, and then executed. An Opcode cache keeps the files compiled in memory and just waits to execute them . So you have essentially cut out a disk read, one reason that an SSD drive is not needed. In most cases SSD drives are faster reading from disk, but if you are not using disk, then you do not need them.
Here are the settings that I use for APC. These settings are for a small store with not a lot of products. These are good settings for you to start out with, you might need to increase them if your cache is filling up and things are getting pushed out too quickly.
apc.max_file_size = 2m apc.ttl = 7200 apc.gc_ttl = 3600 ; means we are always atomically editing the files apc.file_update_protection = 0 apc.enabled = 1 apc.enable_cli = 0 apc.cache_by_default = 1 apc.include_once_override=0 apc.localcache=1 apc.localcache.size=128m apc.num_files_hint = 1000 apc.report_autofilter=0 apc.rfc1867=0 apc.slam_defense = 0 apc.stat=0 apc.stat_ctime=0 ;apc.ttl=7200 apc.user_entries_hint = 4096 apc.user_ttl = 7200 apc.write_lock=1
The most notable values that I am using is that the cache size is 128mb. If you have a larger site you might have to increase this value. I would start moving it up in 128mb increments until your cache stabilizes. Also I have turned the slam defense off as well, it can cause errors being written to your Apache error log. Once you have APC installed, install the apc.php file so you can see how well your site is utilizing the cache.
Once APC is installed and working, you can check your apc.php file to see how your cache is doing, it looks like the image below.
Optimize some files
Mod_pagespeed is an Apache module made by Google to automatically apply some of the Google Page Speed suggestions to your site. Once it is configured it automates the the process of several things that will make your site load faster. Below is a sample configuration that I use for mod_pagespeed.
LoadModule pagespeed_module modules/mod_pagespeed.soAlias /home/bijou/public_html /usr/local/apache/htdocs ModPagespeed on ModPagespeedFetchWithGzip on SetOutputFilter DEFLATE AddOutputFilterByType MOD_PAGESPEED_OUTPUT_FILTER text/html AddOutputFilterByType DEFLATE text/plain AddOutputFilterByType DEFLATE text/html AddOutputFilterByType DEFLATE text/xml AddOutputFilterByType DEFLATE text/css AddOutputFilterByType DEFLATE application/xml AddOutputFilterByType DEFLATE application/xhtml+xml AddOutputFilterByType DEFLATE application/rss+xml AddOutputFilterByType DEFLATE application/javascript AddOutputFilterByType DEFLATE application/x-javascript DeflateCompressionLevel 9 BrowserMatch ^Mozilla/4 gzip-only-text/html BrowserMatch ^Mozilla/4.0 </div> </div>[678] no-gzip BrowserMatch bMSIE !no-gzip !gzip-only-text/html DeflateFilterNote Input instream DeflateFilterNote Output outstream DeflateFilterNote Ratio ratio ModPagespeedFileCachePath "/var/mod_pagespeed/cache/" ModPagespeedGeneratedFilePrefix "/var/mod_pagespeed/files/" ModPagespeedForbidFilters convert_meta_tags ModPagespeedFileCacheSizeKb 102400 ModPagespeedFileCacheCleanIntervalMs 3600000 ModPagespeedLRUCacheKbPerProcess 1024 ModPagespeedLRUCacheByteLimit 16384 ModPagespeedCssInlineMaxBytes 2048 ModPagespeedImageInlineMaxBytes 2048 ModPagespeedCssImageInlineMaxBytes 2048 ModPagespeedJsInlineMaxBytes 2048 ModPagespeedCssOutlineMinBytes 3000 ModPagespeedJsOutlineMinBytes 3000 ModPagespeedEnableFilters extend_cache,combine_css,move_css_to_head,rewrite_javascript,rewrite_images,add_head,rewrite_css,collapse_whitespace,remove_comments,remove_quotes,sprite_images ModPagespeedEnableFilters defer_javascript ModPagespeedEnableFilters canonicalize_javascript_libraries ModPagespeedEnableFilters recompress_jpeg ModPagespeedEnableFilters recompress_png ModPagespeedEnableFilters strip_image_meta_data ModPagespeedEnableFilters insert_image_dimensions ModPagespeedRespectVary on ModPagespeedEnableFilters inline_images <Location /mod_pagespeed_beacon> SetHandler mod_pagespeed_beacon </Location> <Location /mod_pagespeed_statistics> Order allow,deny Allow from localhost Allow from 127.0.0.1 SetHandler mod_pagespeed_statistics </Location> ModPagespeedMessageBufferSize 100000 <Location /mod_pagespeed_message> Allow from localhost Allow from 127.0.0.1 SetHandler mod_pagespeed_message </Location> <Location /mod_pagespeed_referer_statistics> Allow from localhost Allow from 127.0.0.1 SetHandler mod_pagespeed_referer_statistics </Location> </IfModule></pre>This configuration does several things here is a short list of what it will do.
- Takes the white space out of the html resulting in smaller files
- Removes the comments from the html, resulting in smaller file size
- Removes the quotes on html elements resulting in smaller file sizes
- Combines and compresses your css files resulting in fewer http requests and smaller files sizes
- Moves your Javascript to the footer of the page and compresses it, resulting in smaller file sizes and quicker site loading
- Compresses your images which results in smaller file sizes
- If possible it will load Javascript libraries from Googles cdn, which makes your site faster with parallel downloads and also the file could already be cached on the users machine
It does a few more things but those are the main things which it accomplishes.
One note, if you install mod_pagespeed and get an entity ref error, the reason is more than likely that you have the convert_meta_tags filter on. Turn it off, it does not play nice with the Javascript that Prestashop uses in the head of the site. If that does not fix things set the pass through level to on and start enabling filters one by one.
Lets load files faster
What is the quickest way to load files? From memory! If you load files from memory you will get screaming fast performance. The easiest way I have found to load static files is by setting up a reverse proxy on the site. There is actually a WHM module that works really well for setting up a Varnish / Nginx reverse proxy for hosting your static files. It is called Apache Booster. You should install this in your WHM panel. Once you get it installed, this is what I recommend using for your Varnish configuration file.
include "/usr/local/varnish/etc/varnish/cpanel.backend.vcl"; include "/usr/local/varnish/etc/varnish/vhost.vcl"; sub vcl_recv { set req.backend = default; include "/usr/local/varnish/etc/varnish/acl.vcl"; include "/usr/local/varnish/etc/varnish/vhost.exclude.vcl"; set req.grace = 5m; # Handle IPv6 if (req.http.Host ~ "^ipv6.*") { set req.http.host = regsub(req.http.host, "^ipv6.(.*)","www.1"); } # Sanitise X-Forwarded-For... remove req.http.X-Forwarded-For; set req.http.X-Forwarded-For = client.ip; include "/usr/local/varnish/etc/varnish/cpanel.url.vcl"; # Remove has_js and Google Analytics cookies. set req.http.Cookie = regsuball(req.http.Cookie, "(^|;s*)(__[a-z]+|has_js)=[^;]*", ""); # Normalize the Accept-Encoding header if (req.http.Accept-Encoding) { if (req.url ~ ".(jpg|jpeg|png|gif|gz|tgz|bz2|tbz|mp3|ogg|swf|flv|pdf|ico)$") { # No point in compressing these remove req.http.Accept-Encoding; } elsif (req.http.Accept-Encoding ~ "gzip") { set req.http.Accept-Encoding = "gzip"; } elsif (req.http.Accept-Encoding ~ "deflate") { set req.http.Accept-Encoding = "deflate"; } else { # unknown algorithm remove req.http.Accept-Encoding; } } include "/usr/local/varnish/etc/varnish/url.exclude.vcl"; # Ignore empty cookies if (req.http.Cookie ~ "^s*$") { remove req.http.Cookie; } if (req.request == "PURGE") { if (!client.ip ~ acl127_0_0_1) {error 405 "Not permitted";} return (lookup); } if (req.request != "GET" && req.request != "HEAD" && req.request != "POST" && req.request != "PUT" && req.request != "PURGE" && req.request != "DELETE" ) { return (pipe); } if (req.request != "GET" && req.request != "HEAD") { /* We only deal with GET and HEAD by default, the rest get passed direct to backend */ return (pass); } if (req.http.Cookie ~ "^s*$") { unset req.http.Cookie; } if (req.http.Authorization || req.http.Cookie) { return (pass); } set req.url = regsub(req.url, ".js?.*", ".js"); set req.url = regsub(req.url, ".css?.*", ".css"); set req.url = regsub(req.url, ".jpg?.*", ".jpg"); set req.url = regsub(req.url, ".gif?.*", ".gif"); set req.url = regsub(req.url, ".swf?.*", ".swf"); set req.url = regsub(req.url, ".xml?.*", ".xml"); # Cache things with these extensions if (req.url ~ ".(js|css|jpg|jpeg|png|gif|gz|tgz|bz2|tbz|mp3|ogg|swf|pdf)$" && ! (req.url ~ ".(php)") ) { unset req.http.Cookie; return (lookup); } return (lookup); } sub vcl_fetch { set beresp.ttl = 45s; set beresp.http.Server = " - ApacheBooster"; set beresp.http.cache-control = "max-age=90000"; set beresp.do_gzip = true; set beresp.do_gunzip = false; set beresp.do_stream = false; set beresp.do_esi = false; set beresp.grace = 5m; unset beresp.http.expires; if (req.url ~ ".(js|css|jpg|jpeg|png|gif|gz|tgz|bz2|tbz|mp3|ogg|swf|pdf|ico)$" && ! (req.url ~ ".(php)") ) { unset beresp.http.set-cookie; include "/usr/local/varnish/etc/varnish/static_file.vcl"; } else { include "/usr/local/varnish/etc/varnish/dynamic_file.vcl"; } if (beresp.status == 503 || beresp.status == 500) { set beresp.http.X-Cacheable = "NO: beresp.status"; set beresp.http.X-Cacheable-status = beresp.status; return (hit_for_pass); } if (beresp.status == 404) { set beresp.http.magicmarker = "1"; set beresp.http.X-Cacheable = "YES"; set beresp.ttl = 20s; return (deliver); } set beresp.http.magicmarker = "1"; set beresp.http.X-Cacheable = "YES"; } sub vcl_deliver { if ( obj.hits == 0 ) { set req.http.X-Stats-HitMiss = "miss"; } else { set req.http.X-Stats-HitMiss = "hit"; } } # what files to cache sub vcl_recv { if (req.url ~ ".(png|gif|jpg|ico|txt|swf|css|js)$") { return(lookup); } } # strip the cookie before the image is inserted into cache sub vcl_fetch { if (req.url ~ ".(png|gif|jpg|swf|css|js)$") { unset beresp.http.set-cookie; unset req.http.Cookie; remove req.http.Cookie; } } # add response header to see if document was cached sub vcl_deliver { if (obj.hits > 0) { set resp.http.X-Cache = "HIT"; } else { set resp.http.X-Cache = "MISS"; } }One thing to notice, the max age on the static files is set to 90000 seconds. If you update any of the static files on the shop such as change a css file or regenerate your images, you will have to invalidate your cache.
To test if Varnish is installed correctly you can go to isvarnishworking.com and enter your websites address. When you enter a page it should look like this.
What this means is that Varnish is not caching your page files. You do not want Varnish to cache them, the way that Prestashop and other e-commerce programs work it will cause problems if the pages are cached. What you are wanting is for the static files to be cached. Try entering one of your image file addresses in the box on isvarnishworking.com and it should look like the image below.
Some notes about memory usage and other limits
For a site with moderate traffic I would recommend about 2gb of dedicated memory. I usually set the memory at 512mb for php, 128mb for APC, 256 mb for Varnish, and 128mb for the query cache in MySql. The rest of the memory should be left for Apache services and for mail. The limits that you use will totally depend on how large your site is. If your Varnish cache fills up quickly, you should increase it as much as you can to keep files cached. If you have lots of products and modules running you might have to up your APC cache as well, but Prestashop is fairly compact and I haven’t had to raise a shop over 128mb yet. If you are developing a shop and want a real true speed test, I would recommend using New Relic. They have a free tier which will give you a lot of information about how your site loads, without muddling things with network traffic.
Some notes on hosting
Not all hosts are created equal and not all VPS packages are created equal. Here is a short list of VPS providers that I would not recommend.
- A2 Hosting – Their managed VPS accounts do not give you root access, you will need root access to do most of the things that I mentioned here. They do have un-managed hosting, but they do not offer CPanel on their un-managed accounts. You still can set most of these things up without CPanel but it takes more time and skill.
- Hostgator – They also do not give you root access using their VPS accounts, so most of the things are not possible.
- Ramnode – They do offer SSD drives and CPanel licenses with root access, but from my tests their accounts do not have the processing time allocated to them for a quick shop.
- Godaddy – They do offer Cpanel access, but their MySql servers are not hosted locally. This is actually a major reason not to use them, their database latency times jump all over the place, you have no control over them.
Some notes on Prestashop settings
The more modules that you have installed the more resources that your shop will consume and the more processing power that your shop will need. I recommend disabling any module that you are not using and uninstalling the module. Also some other recommendations;
- Disable your shop stats. Stats are nice, but using a properly configured Google Analytics account you can get most of the information that you need. Using the stats consume resources and make MySql calls to your database. I generally disable them.
- I also recommend disabling the minifying html and compressing of Javascript in Prestashop. One, if you are using the mod_pagespeed you will not need this, two out of all of the settings these two add the most time to a being processed on the server.
- Turn error reporting on before you launch your shop and correct any errors that are being reported. Errors in modules will slow the shop down.
- Don’t use a htaccess file. Move the directives from your htaccess file to your httpd.conf file. Loading a htaccess file takes time, having the settings stored in the httpd.conf file will load them from the memory cache and will speed things up on the site.
- Using the default specials and new products blocks will result in a lot of database requests, disable them if you can.
Notes on Google Page Speed, Yahoo Yslow, and GTmetrix
The tips that they give on these sites do not generally speed anything up server side. Think of a website in these terms. The server generates information and sends it to the user. In that transaction their is two places for bottlenecks. The first bottle neck is the server generating the site, the second bottleneck is the users computer decoding the information. Tools like Yslow and Google Page Speed only help speed up the user’s decoding of the files that are sent. They do absolutely nothing for the time it takes your server to process and compile your site. Most of the advice in this article is geared towards getting your site processing faster and delivering content to the user faster.
To illustrate the point, look at this graphic below, it only registers and 82 in the page optimizations, yet it is faster than 93% of loaded sites. http://tools.pingdom.com/fpt/#!/8mQQj/http://bijouthings.com
</div> </div></div></div>
About the Author: Lesley Paone
Lesley has worked in e-commerce for over a decade, and is the founder of dh42. Starting out with PrestaShop and brancing out into other platforms like Shopify. He loves all things e-commerce and loves a challenge, in his spare time he helps moderate several forums on SEO, e-commerce, as well as the PrestaShop forum. If you have any questions for him about any of his articles just use our contact form to contact him.