WordPress: Optimizing Steps

As you know, I have been working with my WordPress installation to improve security, but also to improve site optimization and speeds to download, etc. In this tools such as Google Page Speed and Yahoo YSlow have been incredibly useful. My goal has been to increase the Page Speed and Yahoo YSlow scores to as high as possible. This takes quite a bit of effort to achieve, I had some failed starts, bad plugins, and the need to code things to optimize the site more. So here is how I achieved my current score of 82/100 with Pagespeed. More work will be done with the ultimate goal of achieving 100/100, but that will take quite a bit of coding it appears.

First I should state every site is different and what I do for my site may or may not work for yours, however, sharing this information should help you to decide on how to proceed. First, I have a constant battle and need to do the following on a regular basis:

  • Optimize and resize my images. Pagespeed and Yslow not only want you to specify image width and height attributes within the HTML img tag but they also want those images to be already scaled to the specified width and height as well as perform further lossless compression on image files.
    • Use Google Pagespeed to optimize my unoptimized images for me, then replace the ones on the site with the optimized ones. You have to be careful with extensions as Pagespeed will change the extensions and names of the files to what it wants, but you need to copy them over using the appropriately named files.
    • To properly specify image height and width attributes, I ended up modifying some custom plugins to always output the width and height tags.
    • Modified the theme (or create a child theme) to call my customer plugin functions. You could on the other hand apply this logic to the entire content, but instead I applied it to just the specific functions that required it. That is to do the following style of function, which hard codes the width and height values, and echo’s out the output just like the original function. This approach requires you to look at the existing HTML output to determine the proper strings for the preg_replace.
      function my_plugin_function($args) {
            ob_start();
            plugin_function();
            $output=ob_get_contents();
            ob_end_clean();
            $output=preg_replace("/<img src/","<img width=48 height=48 src",$output);
            $output=preg_replace("/cookie.domain/","cookieless.domain",$output);
            echo $output;
      }
  • Modify the image locations to use a cookie-less domain, otherwise you are sending out kilobytes of data per image when someone is logged into the site. I use the same approach as I did above but add another line (the one with cookie.domain in it above) to replace the existing URL with my cookie-less domain URL, which can be either an entirely new domain or a sub-domain. Either way, it serves up purely static content. This one change, has produced the biggest win.

Now that I have my daily or weekly tasks completed, it is time to launch into other tools to use to improve overall performance. First, let me say, I have used quite a few optimizing plugins within my WordPress install and some work better than others. My first approach was to do it all by hand, which did work, but was not complete enough. The key to optimizing the site is to do the following:

  • Specify Expire Headers
  • Enable Compression
  • Specify Entity Tags for improved browser caching
  • Reduce Request Size
  • Minify HTML, Javascript, and CSS

To do this, I started by using the following:

  • Modify .htaccess file by hand to include Compression, Expire Headers, And Entity Tags, however, this became to hard to manage
  • Use the W3 Total Cache plugin which handled the creation of .htaccess files for me and to a certain extent reduced the request size and applied minification rules. But alas, a later upgrade required me to not only chance my SEO plugin from All in One SEO to WordPress SEO, it also required me to enable more modules within Apache. But also failed to work for some of my more complex lightbox code. So, I ended up disabling the W3 Total Cache plugin but I keep it around so that I can recreate the .htaccess files as needed. I believe this is all related to the fact that W3 Total Cache, just could not find my document root appropriately.
  • Create my own minify tools for various plugins such as GT Tabs. Some plugins do not get their files picked up appropriately by any minify plugin, so I usually have to edit them to add something like this at the front and end of the PHP style script. Granted you could also probably call some other minify tool, but this type of code works as well, mainly because you do not know if the other minify tool is loaded already. Many plugins like Easy Fancyboxalready include this type of minification of CSS.
    <?php
    ob_start("my_minify_function");
    function my_minify_function($buffer) {
         /* remove comments */
         $buffer = preg_replace('!/*[^*]**+([^/][^*]**+)*/!', '', $buffer);
         /* remove tabs and newlines */
         $buffer = str_replace(array("r", "n", "t"), '', $buffer);
         /* and squeeze some more */
         $buffer = str_replace(array(", ", ": ", " {", "{ ", " }", "} ", "; ", " 0;"), array(",", ":", "{", "{", "}", "}", ";", ";"), $buffer);
         return $buffer;
      }
    ?>
    ...Normal file CSS Code...
    <?php ob_end_flush(); ?>
  • Better WordPress Minify is another plugin which will help with minification of CSS and JS which instead of using filters, hooks into the enqueue sub-system to ensure the minification of CSS and JS takes place for all those that are added using the wordpress enqueue calls. The good thing about this plugin, is that not only does this do all the heavy lifting for plugins that use the enqueue mechanism, but it also allows you to point to a cookie-less domain to perform the minification. Most CSS and JS files are static, so using a cookie-less domain also reduces your request size. The bad thing is that any CSS and JS added outside of the enqueue sub-system is not optimized.
  • DB Cache Reloaded Fix plugin helps by creating cache files for common db queries that can stick around for as many minutes as you request. Unlike page and object caching, db caching is most helpful on a site that does not have alot of site updates, as they may not show up right away. This one plugin improved over all performance by removing the more than occasional spike in access time for pages. <== NEW

The use of W3 Total Cache to create and manage my .htaccess files for browser caching, gzip compression, adding Expire Headers, and Entity Tags is very handy even if I cannot leave the plugin on all the time. Better WordPress Minify was the big winner here for my site as it handles minification quite well, and has enough controls to ensure things get performed appropriately. DB Cache Reloaded Fix smoothed out and lowered overall response time on the site.

However, we are not done yet, there are lots of little things that can be done to improve overall site performance using wordpress.

    • Modify CSS of some plugins to remove conditional CSS statements as some add conditionals specific to IE6
    • Reduce redirects which show up when you use Gravatars. There is a default gravatar which you can disable in the system, but it turns and does a redirect to the ‘blank.gif’ 1×1 image inside the wordpress distribution. Redirects like this are time consuming so I added another little bit of code to optimize the selection of my gravatar to be not only from a cookieless domain but to bypass all the redirects.
      function my_get_avatar($avatar,$id="",$size="",$default="",$alt="") {
            return "<img height=1 width=1 src=cookieless.domain/blog/wp-includes/images/blank.gif>";
      }
      add_filter('get_avatar','my_get_avatar');
    • Force the template files for my theme to be served up by a cookieless domain.
      function my_template_directory_uri(template_dir_uri,$template="",$theme_root_uri="") {
            return preg_replace("/cookie.domain/","cookieless.domain",$template_dir_uri);
      }
      add_action('template_directory_uri','my_template_directory_uri');
    • Edit the wordpress-popular-posts.php file of the WordPress Popular Postsplugin to use the functions wp_register_style/wp_enqueue_style over the old method of adding an action to wp_head to output the CSS includes (which is commented out in the following code. This change allowed me to make use of the Better WordPress Minify plugin for this plugins small style sheet plugin, and also fixed a CSS/JS ordering problem per Google Page Speed.
      wp_register_style('wpp.css',plugin_dir_url(__FILE__).'style/wpp.css');
      wp_enqueue_style('wpp.css');
      //add_action('wp_head',array(&$this, 'wpp_print_systlesheet'));

 

    • Edit the theme to pass width and height for the logo image by placing the following at the appropriate place within the header code just before the closing /> of the logo imgHTML tag. Each theme will be different.
      $imagep=TEMPLATEPATH.'/images/'.$bfa_ata['logo'];
      list($width,$height)=getimagesize($imagep);
      echo '" width='.$width.' height='.$height;

 

There are still lots of little things to do with the site to achieve high YSlow and Pagespeed ratings, but they will require a bit more coding. While these tools and techniques greatly assist with this, the incrementals from now become harder and harder. One that would give me a huge increase in ranking would be to use CSS Sprites for small images that I load quite a bit, but to do this, not only do I need to create the sprites but modify plugins and code to use them appropriately. Still left to do are:

  • Combine small images into CSS Sprites for those small images on the site. Some are easier than others.
  • Leverage Browser Caching as any CSS/JS that appears by calling a PHP script has a 30 minute cache time.
  • Optimize the order of styles and scripts
  • minize the request size by offloading more to a cookieless domain
  • minify inline javascript
  • inline some small CSS that Better WordPress Minify did not pick up
  • specify a few more entity tags
  • consider removing query strings from static resources
  • play around with deferring javascript from loading
  • remove AlphaImageLoader CSS commands for IE, unfortunately, if I do not keep these one plugin does not work very well.

If some how I can fix all these issues, I feel the score will climb quite a bit for YSlow and Pagespeed, but the rest of the items to fix require more coding, research, and testing to achieve a higher score. Specifically I will need to:

  • modify plugins or hook into the wp_enqueue_* code in wordpress to change to a cookieless domain, however, wp_enqueue_* functions do not have a filter or action chain which I can use to modify the URL to a cookieless domain. In essence the WP_Dependencies class in WordPress would need to be modified to allow such filters. Not everything can be handled by WordPress Better Minify, specifically elements that require version numbers.
  • Modify more plugins to use wp_register_style/wp_enqueue_style to remove inline CSS as necessary
  • Modify Better WordPress Minify to better minify CSS/JS as it apparently is not as tight as it could be.
  • Find a way to set Expire Headers and Entity Tags for those CSS/JS that contain .php in the name instead of .css or .js
  • Find a way to get CSS Sprites to work across all browsers.

Almost there, but still have quite a bit of work to do.

Edward Haletky

Edward L. Haletky, aka Texiwill, is an author, analyst, developer, technologist, and business owner. Edward owns AstroArch Consulting, Inc., providing virtualization, security, network consulting and development and TVP Strategy where he is also an Analyst. Edward is the Moderator and Host of the Virtualization Security Podcast as well as a guru and moderator for the VMware Communities Forums, providing answers to security and configuration questions. Edward is working on new books on Virtualization.

Leave a Reply

Your email address will not be published. Required fields are marked *

one × 3 =