Speed up WordPress with some optimization

Featured

Hello everyone,
recently I had to optimize a wordpress website that was really slow, in the end I achieved this result:

www.webpagetest.org result

Test done thanks to http://www.webpagetest.org/

I believe it is an acceptable result, it could be better by using a CDN, but I thought it would be not worth the effort (at least for now).

I’ll explain the tools and the procedures I used to speed up the website.

Tools

The above-mentioned tools helped me understanding the situation and where to work to fix one by one all the problems along with WordPress’s Codex.

Operations

WordPress administration interface related operations:

  • Checking the installed plugins:The easier step, and one of the most effective, available. Many WordPress users tend to get overexcited by the huge amount of plugins available and might end up install a lot of them.
    Usually a plugin interact with the database or simply interact with the WordPress installation by implementing new features, widgets, theme modifications, fancy shortcodes, introducing new JavaScript files and/or CSS files bloating the website with a lot of things to handle, this generate 2 important problems:

    1. More database queries
    2. Higher RAM consumption

    This 2 things together will slow down by a lot your website so is important to understand what your website need and what you need and can me implemented with few lines of code.

    Taking as example Twitter, you can find many plugins that will display your recent tweets or allow others to follow you. There is no need to use plugins for something so simple, Twitter is kind enough to offer the code snippets needed to achieve this, they are available here: https://twitter.com/settings/widgets.

    A lot of other situations like this one can be simplified by using snippets offered by the service itself (Facebook, Google+, Linkedin, Instagram and many other offer snippets). Don’t use a plugin when you can instead use few lines of code, it is usually a matter of seconds (copy & paste).

  • Caching:
    Using a valid caching system will enable your WordPress website to go really fast (the access speed to the website I optimized went from 2 seconds to less than 400ms by just adding a wordpress’s plugin to handle the cache).There are many WordPress plugins that handle the cache and allow customization of what-to-cache-and-how but unless you really know what you are doing it is better to grab a simple plugin and enable the recommended options (just keep in mind that recommended doesn’t mean default).I used WP Super Cache and I’m very happy with it, it works without spending hours to configure it and the gain in performance is huge, keep in mind that it is not bug free so keep an eye about updates.

    Few steps are needed to have a basic-intermediate configuration:

    1. From the “Easy” tab select “Caching on (Recommended)
    2. From the “Advanced” tab select:
      • Cache hits to this website for quick access.(Recommended)
      • Use PHP to serve cache files.
      • Compress pages so they’re served more quickly to visitors.(Recommended)
      • Cache rebuild. Serve a supercache file to anonymous users while a new file is being generated.(Recommended)
    3. Again in the “Advanced” tab configure the Cache Timeout and the Scheduler so the stale cached files will get properly removed

    With this few steps you will get a huge boost in access speed but you will have to manually empty the cache (from the Settings menu in your WordPress administration) if you need to have a page or a post updated instantly or wait for the cache timeout.

    You can also use the “Preload” tab to cache every published post and page on your site automatically, be warned that preloading creates lots of files since the caching is done for every post and page (from the newest to the oldest), you will also be able to set the time between each refresh, depending on the amount of visits and other parameters (server resources, frequency of new contents etc…) you may want a short interval (30 minutes) or a larger one (60+).

  • Image optimization:
    From the tool list I mentioned Compress JPG and Compress PNG, they are awesome tools that can greatly reduce the disk space occupied by the images and therefore speed up the website by reducing the weight of the pages, it is important that you also resize the images to the actual needs, there is no need to have skyscraper-sized images for a homepage slider or a showcase, unless you actually want to share such things and even in this case, linking to the bigger image is preferred.

The situation so far

At this point the other optimizations are on the code, if you are not familiar with coding related knowledge (WordPress structure, PHP, FTP/SSH, CSS, JavaScript, HTML, etc…) you may stop reading here and have a partially optimized website, it will perform better than the initial state but it will not be at its better level.

Code optimization

WordPress’s code is not that bad, but some basic changes can be made to optimize it.

  • Script to the bottom:
    Moving the scripts to the bottom of the HTML document is really the most basic and know technique to speed up the pages since JavaScript files block the downloads of the other assets and prevent parallel downloads from any domain.
    To instruct wordpress to move all the scripts to the bottom, you can use this small snippet in the functions.php :

    remove_action('wp_head', 'wp_print_scripts');
    remove_action('wp_head', 'wp_print_head_scripts', 9);
    remove_action('wp_head', 'wp_enqueue_scripts', 1);
    add_action('wp_footer', 'wp_print_scripts', 5);
    add_action('wp_footer', 'wp_enqueue_scripts', 5);
    add_action('wp_footer', 'wp_print_head_scripts', 5);
    
  • Remove unnecessary query tags from CSS & JavaScript files:
    The query tags serve the purpose to always send the correct version of the file regardless the cached version of it.
    This snippet will strip away the query tag, it is also possible to specify a NULL value instead of FALSE or a version when enqueuing the resources, but I haven’t tested it.

    function _remove_script_version($src) {
     $parts = explode( '?', $src );
     return $parts[0];
    }
    add_filter('script_loader_src','_remove_script_version',15,1);
    add_filter('style_loader_src','_remove_script_version',15,1);
    
  • Generic theme optimization:
    Since (almost) everyone use external resources in a webpage (google fonts, social network widgets, tracking codes, CDNs for JavaScript libraries, etc..) it is important to keep in mind that each request to an external source will incur a DNS lookup.To avoid that, you have to modify your <head> with few lines of code that will prefetch the DNS as soon as possible speeding up the process.Here a snippet that will show the most use of the DNS prefetching technique on the most commonly used domains:

    <link rel="dns-prefetch" href="//fonts.googleapis.com">
    <link rel="dns-prefetch" href="//platform.twitter.com">
    <link rel="dns-prefetch" href="//www.google-analytics.com">
    <link rel="dns-prefetch" href="//themes.googleusercontent.com">
    <link rel="dns-prefetch" href="//p.twitter.com">
    <link rel="dns-prefetch" href="//cdn.api.twitter.com">
    

    More information on the topic is available here: http://calendar.perfplanet.com/2012/speed-up-your-site-using-prefetching/.

  • CSS homepage optimization:
    Assuming you are still reading, I would like to share the tool I’ve made while working on the homepage optimization.I believe that the homepage is a critical part of the website, and should then (if/when possible) perform as better as possible (would be better if the performance was great on the whole website of course).Since I’m not (yet) a master in the ways of Shell my script is not the best around, and I’m sure it can be a lot better, but it get the job done.

    The idea behind the tool is to take in input the list of the CSS classes thare are not used in the homepage (thanks to the Google Chrome’s Audit tab of the developers tools) and the CSS file(s) that are used (after formatting it with this tool with the option “Insert a line breaks after ‘}’ characters.”) and it will output a new file that will not have the unneded classes.

  • .htaccess caching management:
    Assuming you can’t modify the virtual host configuration, you can modify (and should) the .htaccess file to define directives that will help speeding up the website.From apache.org:

    You should avoid using .htaccess files completely if you have access to httpd main server config file. Using .htaccess files slows down your Apache http server. Any directive that you can include in a .htaccess file is better set in a Directory block, as it will have the same effect with better performance.

    There are few modifications possible:

    • ETag removal:
      More information available here: http://developer.yahoo.com/performance/rules.html#etags.

      # 'FileETag None' is not enough for every server.
      <IfModule mod_headers.c>
       Header unset ETag
      </IfModule>
      FileETag None
      
    • Far future expire header:
      With this few lines of code we set the expiry date to 1 year in the future.

      <IfModule mod_headers.c>
       <FilesMatch "\.(ico|pdf|flv|jpg|jpeg|png|gif|js|css|swf)$">
        Header set Cache-Control "max-age=31536000, public"
       </FilesMatch>
       <FilesMatch "\.(html|htm)$">
        Header set Cache-Control "max-age=31536000, must-revalidate"
       </FilesMatch>
      </IfModule>
      
  • Other .htaccess modifications:
    Lastly we can also force Internet Explorer to always show the website at latest version, it may fallback to IE7 and if it is available it will use ChromeFrame if it’s installed.

    <IfModule mod_headers.c>
     Header set X-UA-Compatible "IE=edge,chrome=1"
     <FilesMatch "\.(appcache|crx|css|eot|gif|htc|ico|jpe?g|js|m4a|m4v|manifest|mp4|oex|oga|ogg|ogv|otf|pdf|png|safariextz|svg|svgz|ttf|vcf|webm|webp|woff|xml|xpi)$">
      Header unset X-UA-Compatible
     </FilesMatch>
    </IfModule>
    
  • Apache configuration:
    To maximize the speed of the connection it is also important to correctly configure the Keep-Alive setting to allow a single HTTP session to permit mutliple requests to be sent over the same TCP connection. More information are available at the apache.org website.

And that is all, it took me a lot of time, but I’m more than happy to share my knowledge and discoveries with everyone who care about this stuffs.

The WordPress website I optimized is www.oss4b.it and here is a recent report about the situation on the website.

Unfortunately I didn’t had the chance to work on the database optimization, but I’m looking forward to try Percona Server as I was lucky enough to be at the conference and speak with a Percona expert, was very interesting!

I’m open to questions and suggestions as I believe some things could have been done better and that there are a lot of tools that I don’t know of!

Enjoy!

Magento google sitemap generation for multistore installation

MagentoHello everyone,
if you ever need to have a sitemap for each store created under a single Magento installation, you will probably face a little error about the unavailability of your specified path for the creation of the sitemap.

Regardless of the path you may specify, you will get the following error all the time:

Path "mypath/mysitemap.xml" is not available and cannot be used.

As you can imagine the problem is not very clear as the error is misleading to a different source.

As today (Magento 1.6.x) the only way to avoid the problem, without touching core files that is, is to understand that Magento want a specific name for the sitemap, and it will not accept anything else:

sitemap.xml

However, to have more sitemap.xml, one for each storeview, you will need to manage sub-paths, like:

myrootfolder/sitemaps/mystoreview_[1,2,3...,n]/sitemap.xml

If you would like a clean approach you can, however, work with the rewrites to let the Apache serve a clean url for the sitemap:

RewriteCond %{HTTP_HOST} ^.*yourstore_1\.com$ 
RewriteRule ^sitemap.xml$ yourpath/sitemap.xml [NC]

Enjoy!

P.S.:

Also available in dutch!
http://www.byte.nl/blog/2012/08/10/sitemap-maken-in-een-multistore-magento/
http://www.dutchento.org/sitemap-maken-in-een-multistore-magento/#more-3555

Magento Dataflow profiles with over 8k products

MagentoIf you are trying to export products from Magento’s Dataflow profile, and you have more than 8000 products, it is common to end up with an error 500 without many information.

To be able to handle that from the web interface without running a profile from the shell, you have to tell your fcgi to be patient!

Here is how to do so:

FcgidBusyTimeout 3600
FcgidIdleTimeout 3600
FcgidProcessLifeTime 7200

Here some more specific informations.

Enjoy!