Skip to a section of this page:

Archive for the ‘Wordpress’ Category

My first public WordPress plugins

Monday, March 22nd, 2010

I’ve been playing with WordPress for a fair while now. Hacking together themes, trying and modifying existing plugins, writing my own simple plugins from time to time. Generally doing too much in the theme files, and not enough abstraction into proper plugins.

Recently I’ve decided it’s time to bite the bullet and formalise some of these hacks, so I bring you my first two public WordPress plugins:

  • Custom default avatar

    Plain vanilla WordPress provides a list of default avatars to choose from, but doesn’t allow you to choose an image of your own making. This plugin allows you to specify your own default avatar

  • Custom app icons

    This plugin allows you to specify icon(s) to be used when iPhone / iPod Touch users create a shortcut to your site using the ‘Add to Home Screen’ function in Safari

I hope you find these useful, and eventually I will think about submitting for inclusion in the Wordpress.org plugin directory. Before I do however, I’d appreciate any and all feedback, for example: any functionality limitations, plugin faux pas, coding style issues, etc…

Let me know what you think!

WordPress performance revisited

Sunday, December 6th, 2009

Stefano asked if I had numbers to back up my previous performance claims regarding WordPress performance plugins. Today I ran some tests to be able to provide those numbers.

All tests were performed:

Results

The “baseline” results represent tests without DB Cache Reloaded, Hyper Cache, or GZIP Output plugins installed. Different combinations of these plugins were then tested. Each combination was tested 10 times and the results have been averaged.

This site (irama.org) — number of seconds to render HTML of the homepage
test baseline DB Cache Reloaded Hyper Cache DB Cache Reloaded + Hyper Cache DB Cache Reloaded + GZIP Output
1 0.325 0.294 0.299 0.409 0.292
2 0.458 0.447 0.322 0.318 0.335
3 0.366 0.267 0.493 0.290 0.313
4 0.287 0.299 0.765 0.331 0.269
5 0.740 0.319 0.393 0.311 0.512
6 0.807 0.276 0.315 0.435 0.354
7 0.351 0.270 0.348 0.280 0.343
8 0.347 0.403 0.361 0.292 0.290
9 0.412 0.298 0.321 0.336 0.263
10 0.418 0.263 0.286 0.364 0.267
Avg. 0.451 0.314 0.390 0.337 0.324
A more complex client site — number of seconds to render HTML of the homepage
test baseline DB Cache Reloaded Hyper Cache DB Cache Reloaded + Hyper Cache DB Cache Reloaded + GZIP Output
1 3.116 2.477 2.198 2.287 2.693
2 2.663 0.749 2.542 0.712 0.895
3 2.820 1.008 2.382 1.143 1.221
4 2.390 0.799 2.501 0.827 0.880
5 2.304 0.758 2.581 0.939 0.939
6 3.348 0.795 2.364 1.068 1.109
7 3.150 0.866 2.248 2.483 1.172
8 3.139 0.989 2.512 1.125 0.912
9 3.115 0.789 2.667 0.939 1.092
10 2.525 0.776 2.306 2.613 0.910
Avg. 2.857 1.001 2.430 1.414 1.182

Analysis

My previous recommendation of Hyper Cache was primarily because it provides GZIP compressed HTML. Since the results for DB Cache Reloaded + Hyper Cache were not as strong as DB Cache Reloaded alone, I looked for an alternative plugin that might provide GZIP compression without as much of a page render performance cost.

I tested the GZIP Output plugin, and while it still seems to negatively impact on page render time, I believe the addition of GZIP compression — which will lower the size of the transmitted HTML file — is worth the small hit on render performance.

Note: If your web server compresses HTML output from PHP files automatically (or it can be configured to do so) then use that approach instead of using the GZIP Output plugin as it is likely to perform slightly better. The other benefit of this approach is that compression will also be applied to the HTML output of PHP files that are not part of WordPress (if you have any).

Conclusion

In terms of performance (on a shared hosting environment) disk IO is expensive, but DB access is more expensive. So while Hyper Cache alone makes a difference, DB Cache Reloaded makes a greater difference. YMMV, but in light of this data, I would update my recommendation…

For best WordPress performance, use the following plugins:

  1. DB Cache Reloaded
  2. WP Minify
  3. GZIP Output (only if your web server doesn’t GZIP HTML output from PHP automatically).

Note: If DB Cache Reloaded is not an option with your hosting provider, or you aren’t able to get it working, Hyper Cache is still a good option (remember: you won’t need GZIP Output if you have Hyper Cache installed).

Finally…

I hope this helps. Let me know if you have feedback about my methods/results, or if you have other WordPress performance tips.

WordPress performance

Friday, December 4th, 2009

Update 5 December 2009: Recommendation revised based on new data.

As promised, here’s a quick rundown of the WordPress performance plugins I’ve been using.

  • DB Cache Reloaded = Big performance wins. Especially on shared hosting.
  • Hyper Cache = Less noticeable improvement than DB Cache, but still noticeable.
  • WP Minify = Essential. Every website should combine, minify then cache static text assets (like CSS and JavaScript) for production.

Note: I have used WP Super Cache in the past and have run into problems. Apparently it doesn’t perform too well on shared hosting setups. Also, in my experience, DB Cache outperforms Super Cache every time.

I have other thoughts about web performance that I’d like to share, but not today. Let me gather my thoughts some more and get back to you.

Know of any other good WordPress performance tricks? Leave a comment.

So long MT, G’Day DH

Friday, December 4th, 2009

Well, it wasn’t easy, but I’ve done it: I have migrated my sites away from MediaTemple (MT) to DreamHost (DH).

Why the change? Performance mainly.

MediaTemple has given me decent stability and good support over the last few years. And most of all I’ll miss that gorgeous, minimal admin control panel.

But the performance has been poor at best. Even with WordPress caching plugins installed, page renders averaged 3 seconds, not including the fairly frequent spikes (of up to 30 seconds) which would occur every 5 attempts or so.

And while they seem to have more constant outages (two of which have affected me already), the overall page render performance at DreamHost has been at least twice as good (< 1 second for page render on average) as MediaTemple and far more consistent (i.e: no spikes). For those who are interested, without caching plugins installed, the difference was far more pronounced (averages of 13 seconds for MT and 2 seconds for DH).

The DreamHost control panel isn't quite as minimal or as gorgeous, but it is much better organised than others I tried, and has all the functionality I require.

I should note here that these performance results (especially the DreamHost results) are based on a limited period of testing. So I’ll keep you posted as to the service and performance longer term. But it is safe to say that the performance of my previous provider has been less-than-ideal for a long time, hence the move.

For those interested in WordPress performance, I’ll post a follow up about the plugins I’m using.

First contact

Sunday, March 8th, 2009

I finally have a contact form! Thanks to the close-to-perfect Wordpress plugin Contact Form 7.

I say “close-to-perfect” because of two fairly minor flaws (these observations are based on Wordpress v2.7.1 and Contact Form 7 v1.9.3)…

Flaw the first: Accessible form markup

The plugin seems to output a bunch of non-semantic markup (<span>s, etc…). I’m just going to ignore them because I figure they aren’t doing too much harm.

The bigger issue is that using the default form template, form control labels aren’t marked-up using the <label> tag! This issue has an easy fix, because the plugin’s author iDeasilo has thoughtfully allowed for customising the output markup.

Here’s the template markup I settled on:

<div id="contact-form">
<p class="instructions">Required fields are marked with
<abbr title="(required)" class="req">*</abbr></p>
<ul>
	<li class="input required"><label for="your-name">Your Name
		<abbr title="(required)" class="req">*</abbr></label>
		[text* your-name id:your-name]</li>
	<li class="input required"><label for="your-email">Your Email
		<abbr title="(required)" class="req">*</abbr></label>
		[email* your-email id:your-email]</li>
	<li class="input"><label for="your-subject">Subject</label>
		[text your-subject id:your-subject]</li>
	<li class="input"><label for="your-message">Your Message</label>
		[textarea your-message id:your-message]</li>
	<li class="submit"><strong>[submit "Send"]</strong></li>
</ul>
</div>

I also added the following CSS to my stylesheet to make the form prettier:

#contact-form ul,
#contact-form li {
	margin: 0;
	padding: 0;
	list-style-type: none;
	overflow: hidden;
	zoom: 1; /* For IE6&7 */
	margin-bottom: 1em;
}
#contact-form li {
	position: relative;
	padding-left: 1em;
}
#contact-form label {
	float: left;
	clear: left;
	width: 10em;
	margin-bottom: .2em
}
#contact-form input,
#contact-form select,
#contact-form textarea {
	float: left;
}
#contact-form .submit {
	padding-left: 11em;
}
#contact-form abbr.req {
	color: #f00;
	font-weight: bold;
}
#contact-form .required abbr.req {
	position: absolute;
	left: 0;
	top: .2em;
}

The markup and style above are based on forms code ideas Ben and I have been refining for the last few years (which in turn are based on ideas from other web developers far and wide, I’m sure Ben will post about it in more detail later).

This version works well for a simple form like this. The form controls wrap under the labels at smaller resolutions, and the required field indicators always sit in their own column.

If you are a purist, you can separate the zoom: 1; line into a separate stylesheet and serve it to IE6 and 7 only using conditional comments.

Flaw the second: Automatic addition of <br /> to output

This issue is a little prickly, because there’s no way to turn this “feature” off in the plugin configuration.

A workaround has been suggested, thanks Aiden!

Unfortunately, implementing this workaround means I would need to remember to edit this file every time I update the plugin.

I have a slightly different solution, based on Aiden’s idea that means the plugin can be updated and this preference should remain intact.

Because the plugin checks to see if the constant is defined before setting it, if we set the contstant first, our value will not be overwritten by the plugin.

Add the following code to the top of your wp-config.php file:

// Contact Form 7 plugin: Don't add <br /> tags!
	define('WPCF7_AUTOP', false);

Remember to keep this part of the wp-config.php file when you next upgrade Wordpress.