Besides installing W3 Total Cache or another caching plugin what steps can I take to make sure that my theme and site run as fast as possible.
|
You could install WordPress on Nginx. There are a number of resources to help: Some performance information from that last link (which appears to be a bit different setup than the others):
|
|||||||||
|
|
Set client-side expiries for things like css, images, JavaScript etc which don't need to be redownloaded for each page view. This, by far, made the biggest difference to my site loading times. The fastest download is the download that never happened ...
You may pre-gzip everything you reasonably can (7-zip is a good tool for this) & upload it in the same place as the file you just gzipped. Change .htaccess to serve the pre-gzipped files, as below. The caveat here is you need to remember to re-gzip them if/when you update things. This cuts out the CPU overhead, apart from parsing .htaccess.
This is just a raw answer. There are a lot of variations on this theme. I blogged about this and added quite a few references to more in-depth articles at http://icanhazdot.net/2010/03/23/some-wordpress-stuff/. Read that and, more importantly, the references I point to - they are good resources. Be aware that if you tinker often then users will need to refresh their cache. A plugin I found very useful too is wp-minify. The thing to watch with this one is that you should exclude page-specific items (contact form, front page slider etc) so you're not re-downloading the whole set of css, JS etc for each page. It is a good way to minify, combine & compress your baseline CSS, JS etc. It cuts down on http requests a lot. Wp-minify plays well with supercache and also with expiry headers that I detailed above. Use Yslow in Firebug (Firefox) or similar to monitor your http requests and what is and isn't compressed. Have a look at expiry headers in there too. You will soon see what you can improve. |
|||||||||||||||
|
|
Minimize the number of plugins you run to only what you really need. Especially be aware of plugins that add javascript and CSS code on every page load, even when that code isn't being used on the page. If you are creating your own theme from scratch, break your CSS down so that features that are only need for particular page templates or view types (single post, archives, category, etc) are only loaded when needed. Configure W3TC to use a CDN (like Amazon CloudFront, or any of the others supported by W3TC). See if the Minify options work for you (some plugins generate js/css that won't minify nicely, so be sure to test your site after activating the minify feature). If you have full control of your MySQL server, make sure that you have the query_cache turned on. Use a MySQL tuning script to find other ways to optimize your database config. If using a CDN is problematic for some reason, configure mod_expires in your apache setup. Set expiration times as long as reasonable for static types like images, css, javascript, video, audio, etc. |
|||
|
|
|
Run memcached and use an object cache to reduce the number of database queries. This caches data from the database, rather than pages. Not sure if w3-total-cache already does this. Make sure you are running an opcode cache like APC. (There are several more available.) |
|||||
|
|
A few answers off the top of my head: 1) Minimize the number of HTTP requests the browser has to make to your host by concatenating JavaScript and CSS where possible/practical. 2) Offload as much of your image/media serving to 3rd party CDNs as possible, particularly if you're using shared hosting. 3) Try reducing the number of posts you're displaying on the front page in order to cut down on total render time. 3a) Try using a theme that presents a few featured posts in full on the front page and all other, older posts as excerpts. |
|||||
|
|
In addition to using a disk caching plugin like wp-cache, put your blog on a host volume that has the "noatime" property set on it. Otherwise, SSH into your host (if your webhost provides that) and routinely run this command on your files every few days:
The ~/* means "my files under my home directory". You can change that path as you see fit. You can also set this up on a cron job in cpanel if your webhost provides that. For more info about atime property, see this. It speeds up Linux disk read performance greatly. Sometimes your site is being hammered by spiders. You can use a tool like SpyderSpanker or Chennai Central to filter out spiders who don't help bring more page rank to your site and merely slow it down, and then throttle good spiders (like Google, Bing, etc.) by sending them random HTTP 304 Not Modified messages. Another thing I see is just poorly written plugins. If you learn how to make plugins, you begin to see how some plugins are inefficiently coded, or even find timebombs, such as a database table that fills and fills and never gets cleaned out, storing things such as incoming connection data. Beyond all the other solutions here, you can also create a WordPress web farm of your blog by hosting it on several web node PCs that all connect back to one single database and one single disk volume for the files (such as a volume mounted over NFS). Check out Ultra Monkey for how to get that all going. |
||||
|
|
|
Use a database class that is trimmed for optimization. We made good experiences with own code to reduce memory usage and database access speed. Next to that, you can optimize the database structure itself by some small changes that do a lot as well. Part of the database class code can be found in the wordpress trac, it did not made it into core (Ticket #11799 and related). |
||||
|
|
I recently spoke about this subject at WordCamp Houston. All of the above recommendations are great and the important thing is to make sure all the front end stuff is fully optimized then you can start working on the caching and server performance issues. Progressive rendering will make your pages feel faster because the user will see the page content before it is fully loaded. To do this make sure any blocking js is at the very bottom of the page and css is at the top. Also if you use a lot of social media buttons you can customize the scripts to make them load in an iframe after the page is fully loaded. I wrote a tutorial on how to do it with the TweetMeMe re tweet button (now obsolete since Twitter released their own retweet button) but can still be applied to other share buttons. For server performance look into Nginx as a front end proxy for static content with Apache handling the heavy PHP and MySQL lifting. |
|||
|
|
|
For a highly trafficked site, you should tune all MySQL buffers for the content that is in place now. Regardless of the version of WordPress, the MySQL layer can have its configuration computed. In fact, if you have InnoDB data without enabling innodb_file_per_table, you need to cleanup InnoDB by segmenting each table into its own physical tablespace. It is possible to do decent MySQL tuning even if you have a limited hardware. There are many scenarios for doing such InnoDB optimizations. IMHO, you cannot plan good settings for my.cnf without knowing the amount of data to configure for. You would have to periodically load a current dataset from production into a staging environment, perform optimizations and come away with the numbers to configure in the my.cnf of the production server. |
||||
|
|
|
you could enable global output compression. this will gzip everything going out automatically if the browser supports it. This drastically reduces the size of files transferred, but does increase your CPU load. |
|||||
|
|
Since nobody mentioned it yet, one of the most important steps to enhance server performance in conjunction with any LAMP setup would be to switch to apache worker thread and mod_fcgid. This freed up 500MB of memory on my virtual private server. |
|||||||||
|
|
Caching the WordPress Menu also gives you a performance boost. Especially if you have a lot of Pages or a giant Menu Structure, this should be considered. Do it in 2 easy steps. At first, create a function that gets or creates the menu, instead of calling
In your theme, replace the Menus don't change often - but you also have to hook into the Do it like this:
The Menu will be generated the next time the page is called - and use the cached version until someone updates the menu again. Updated Version Thanks @helgatheviking for pointing out a mistake between slugs and IDs. I updated the functions so it works both with The menus are always saved with the name of the Menu, not the position in the Theme. |
|||||||||
|
