More WordPress Performance Optimization
General WordPress performance info
After all static files to cdn and move javascript out of html header. I also enabled multi CNAME cdn to see whether it increase page loading speed(not enabled in my cdn plugin yet, still testing). Here is the resault,
It seems CSS loading will still block css background images even those included in main html header. I also used Varnish to front proxy WordPress, because WordPress becomes extremely slow after move database from MyISAM to InnoDB.
Updates: I found 2 website helping draw water fall chart. Pagetest by AOL and Site-Perf.com.
Updates 2: I partly solved css image not preloading problem by insert an invisible img tag like this,
<img src="http://m1.cdnyy.com/x/wp-content/themes/aeros/images/autumn.jpg" alt="" height="1" width="1" style="border:0;display:none" />
But this only work in Chrome. IE will not load any image before css loaded.
Look at loading time of autumn.jpg, near 200ms improvement in Chrome.
How to use SimpleCDN with WordPress
Update 2/24/2009: This method is deprecated. I wrote a plugin to rewite urls.
Update again: SimpleCDN is slower comparing to CloudFront, I moved all my link to CF. If you have problem copying files to S3, you can read this post.
WordPress is my favorite bloging software, with many builtin features and powerful plugins. WordPress.com, the blogging platform by automattic, has been using CDN for a long time. However there is no public available solution to make self hosted WordPress to use a CDN as well. Fortunately the php code itself is very clean to read, so it took me about 5 minutes to find where I should modify to fully integrate my new CDN address.
Before you proceed, please read my previous posts on how to use CNAME with SimpleCDN and how to process javascript and css files for WordPress. Make sure your SimpleCDN’s CNAME and bucket working properly. I used a mirror bucket which points to my blog address, that is probably the simplest way to mirror your static assets. And use ‘-s1′ pre-url to insure client side cache working, because SimpleCDN does not use 304 not modified http header at all. I used bucket name ’s.mudy.info’ for my own blog.
Once your DNS full propagated, open your favorite text editor open following 3 files.
‘wp-includes/class.wp-scripts.php‘: near line 75, change
$src = $this->base_url . $src;
to
$src = 'http://yourcdnbucketname' . $src;
There is no trailing slash after your bucketname. If you want to make sure client browser always use cached version, you can also comments out the following line.
// $src = add_query_arg('ver', $ver, $src);
But this change may break WordPress upgrade.
‘wp-include/class.wp-styles.php‘: near line 79, do the same change as above.
‘wp-include/theme.php‘: near line 504, change
return apply_filters('theme_root_uri', content_url('themes'), get_option('siteurl'));
to
return 'http://yourcdnbucketname/wp-content/themes';
That’s it. Now clean your cache and test your blog.
Optimize WordPress javascript placement
YSlow rule 6: Put JS at the bottom. This is a very simple rule, but it has noticeable improvement on actual page loading time. Because javascript in head will block both page elements loading and rendering. The placement of javascript in WordPress 2.7.1 is hard coded to be placed in html head, because most ajax plugin would expect javascript library to be fully loaded before page load. If you use WordPress without any fancy ajax related plugins, it is very possible to load javascript at bottom of every page without breaking any blog function. I also tested it with Lightbox 2 without any noticeable problems. The measurable page loading time difference is near half a second when browser cache is empty. Before you proceed to make any change to WordPress php files, I would recommend you to do a full backup of database and related php files. Now open ‘wp-includes/default-filters.php‘, search wp_print_scripts. Near line 184, you should find,
add_action('wp_head', 'wp_print_scripts');
Change this to
add_action('wp_footer', 'wp_print_scripts');
Clear your WordPress page cache and test your WordPress. Ideally one could write a plugin hooking into filter ‘print_scripts_array’ to remove plugins from html head conditionally. But I have not found one yet. There are a lot other methods to safely speedup javascript loading in html header. Unfortunately they are not very easily implemented and cross different browsers. Steve, author of Yslow had a post and talk explaining the whole situation.