Speeding Up Your WordPress Blog

Speeding Up Your Blog

Because it’s been annoying me more than usual, I want to keep this theme because I don’t need to waste time trying to get another one up to speed, and I’m going to be on a shared host for some time to come (thank you, economic downturn).

You might not need to do this (I personally am obsessive). Indeed, it takes some time and knowledge to do some of the more serious items on this list.

General Approach

  1. I killed every plugin I didn’t absolutely need, especially the ones that add more filtering execution time to my posts. They’re usually the ones with special tags/short codes.

  2. I learned how to use page templates and built-in WordPress capabilities to remove more plugins and filtering.

  3. WP Widget Cache is awesome. I can include some of the more expensively queried widgets (blogroll and categories) and automatically achieve caching on my RSS widgets. That cuts the number of queries my front page needs in half while keeping interesting parts around.

  4. Since my RSS widgets are now cached with the WP Widget Cache, I killed every widget containing Javascript, which always hit some service remotely and never cache.

  5. I removed as many plugins as possible that require cron jobs (e.g. regular executions of something or other), especially if they hit my site often (which is how WordPress cron jobs usually work).

  6. I used to have redundant website metrics trackers for my site (they all tell you different things). No more; I’ve settled on Mint. ((For people interested in free, and who wouldn’t be, yet still want live statistics rather than Google Analytics‘ delayed statistics, look into Woopra or WordPress.com Stats (which also work for independent sites).))

Below the cut: stuff I kept, stuff I dropped, detailed reasons why, and replacements if applicable. This list is long, but there are some interesting plugins listed down there.

Keeper Plugins and Widgets

  • Akismet: Cannot live without. Spammers would eat me.

  • All in One SEO Pack: Invaluable for better page titles, meta keywords, removing superfluous search engine indexing of your category/date archives ((I mean, Google already indexes your front page, its successive pages, and your individual posts. I still let Google index my tag archives, though, because those are most useful for SEO.))…

    I could implement all this myself, but since the SEO pack already effectively does that, I wouldn’t remove much in the way of execution time, though I might reduce queries by a bit. But the effort outweighed keeping it around.

  • Bad Behavior: Cannot live without. Spammers would eat me even more.

  • Code Markup: Considering that I use this heavily to demark code in my popular HTML for Dummies and also the various scripting posts I’ve written, which involve large amounts of code, I need it.

    It’s a post filter, and I could live with using a lot of > and < but again, too much effort.

  • Compact Archives: Generates the very nice and tight Archives widget under my Calendar widget (if the Calendar’s still there; it uses a lot of queries and also isn’t cacheable, since it needs to change to the right past month when you view individual date-based archives). It adds a PHP function, not an extra short code to filter posts through, so it didn’t add more execution time and isn’t worse than the built-in WordPress Archives widget. In fact, it generates less HTML code than the built-in.

  • Decategorizer: Strictly speaking, it builds off the Redirection plugin and adds a bit more time, so it’s something that I can drop. Unfortunately, it would break a lot of links, so currently too much effort.

  • Exec-PHP: Adds a little bit more filter (though not as much as short codes do, surprisingly) and actually is a bit dangerous to play with if you don’t know what you’re doing (I do. Mostly). However, it lets me have a Compact Archives widget (which doesn’t come with a widget, so I need to make its PHP call either as part of the theme or in an Exec-PHP-enabled widget text box). Very, very useful.

    I had an older Exec-PHP-Widget plugin that added a PHP widget, but that was redundant in light of Exec-PHP, so I dropped it.

  • FD Feedburner Plugin: Better in configuration/features than the Feedburner Plugin that was recommended on the Feedburner help page, and still small. I prefer Feedburner, because then all the RSS readers hit it instead of my site.

    (Feedburner still hits my site every 30 minutes, but that’s still preferable and doesn’t really crowd out my visitors.)

  • Google XML Sitemaps: The best and least intrusive Sitemap generating plugin. Site maps: good for search engines to occasionally pull down and use as hints to how to re-index your site. It only regenerates when I make a post (or explicitly click a button on its settings page). Valuable and doesn’t add execution load to site renders.

  • In Series: One of my most expensive plugins in terms of adding database queries. But I write too many series articles, and the Hugo Awards happened to be 20-some posts long. This can be taken care of by manual linking, but frankly, too much effort for me at the moment.

    Plus with all the other cuts/improvements, my site typically generates on the server side in 0.25 seconds or less, even on a series-heavy page. Not a concern of mine as of yet.

  • KG Archives: While this plugin adds a shortcode, it’s also a shortcode filter with an extremely efficient regular expression, with a tiny target range of pages to parse (e.g., pages named ‘Archives’). It’s the one that generates my post-by-post listing per month on my Archives page, and it’s valuable for people who want to browse my archives quickly. Including search engines.

  • Lighter Menus: Reduces menu space on my administration pages by a lot; I strongly recommend this plugin. It doesn’t add rendering time for my site visitors, so it’s a definite keeper.

  • Live Journal Crossposter: I know some folks on LiveJournal who prefer to stay there. My approach is: bring myself to my audience, and not the other way around. ((Where I work has a very customer-based approach, as you can imagine. We hire for it. Hence that focus on my blogging and… well… everything else.)) This only adds time to when I create a post, not site generation time. Invaluable for me.

  • My Category Order: Only adds a widget that allows me to order the categories however I wish, and also easily exclude categories. For a blog with a ton of subcategories that no longer apply as much to its current focus, and categories to de-emphasize with respect to same changed focus, valuable.

  • My Link Order: My fourth-most valuable plugin, because it allows me to order my blogroll’s categories however I wish. So I can prioritize Kindle over eBooks over SFF ((FSF?)) over Everything Else.

  • No Self Pings: Self-pings are messy to me and add more in the way of trackback removals—a lot, because I often refer to older posts in my newer ones. This only adds time for posting, not site generation, so it’s a keeper. And my third-most valuable plugin.

  • pageMash: Makes re-ordering pages much easier. Doesn’t add any execution time at all to site rendering. Win.

  • Redirection: Used by the Decategorizer and also has a lot of redirections for posts that no longer reside here (like a lot of the Holmes posts and fiction stories). This adds only a tiny bit of time, (one query and the redirects are 301s, so that search engines eventually get a clue and the actual Redirection work is invoked less and less.) My second-most valuable plugin.

  • Search Unleashed: A much better search, with actual regular expressions and search operatives, and also highlights search words from my site or from Google and other search engines. Very nice, slightly expensive but only on search results.

  • Simple Feed Copyright: I didn’t need much fancy stuff, and this adds some static text to the end of every RSS entry. Only invoked for feed rendering. A keeper in this age of much RSS scraping and content stealing.

  • Simple Tags: It can generate a better tag cloud than the 2.x WordPress function (changing colors do much to alleviate the pain that looking at tag clouds can sometimes induce) without worse performance. I removed its shortcode ability (a setting on its page, which is nice) and use the PHP function directly in one page. ((As a specific page template, which saves more time but also is not a beginner’s subject.))

  • Sociable: Better than creating post-specific social media links for every page myself, and does not really any worse (plus I can add more options easily, and re-order them).

  • Subpage Listing: Invoked as a PHP function, and then only for specific pages. I could write the function myself or… just use one that someone else wrote. And so it stays.

  • Twitter Tools: It posts new posts automatically to Twitter (with TinyUrls, and also is smart about not duplicating tweets even on subsequent page edits) and caches tweets from Twitter, so it doesn’t eat into my Twitter call allowance every time my page is loaded. Comes with nice widget. Win.

  • WordPress Automatic Upgrade: This has so much win and adds zero in page rendering time. Go get it if you run your own WordPress installation and make the process of upgrading your WordPress installations pretty much painless.

  • WordPress Download Monitor: It counts numbers of downloads and does add shortcodes, but otherwise it’s innocuous and the least feature-filled (read: least expensive) download plugin to have around. As I do create eBooks, this is handy.

  • wordTube: At some point I may actually make decent use of this plugin other than for playing little MP3 clips cut at specific places. It adds shortcodes. I wish I didn’t need it, but there are very few flash mp3 players out there that are (a) stable, (b) small, (c) efficient, (d) don’t disappear after four months.

  • WP DB Manager: It occaisonally cron-jobs to clean up indexes in my database and thus make it faster, and adds no rendering time (and, indeed, improves it). Win.

  • WP Footnotes: It’s not a shortcode, but it does still add rendering time via post filtering, and does have a shortcode-like aspect in how you demark footnotes. But I like it too much to drop unless there’s no other option.

  • WP Print: Adds a print link to every post; it’s a PHP function, so it’s directly in my templates. This takes you to a very light version of any of my pages or posts, instead of requiring you to print it out like a @media print CSS stylesheet would do (which would also still require people to load a ton of HTML code that won’t be rendered, so why do that to them?).

  • WP Ajax Edit Comments: Lets my users edit their posts. This is a nice thing, and probably the most valuable commenting feature to any user. It stays.

  • WP Widget Cache: As I mentioned above, WP Widget cache is love. If it were not for this plugin—which can regenerate specific widgets depending on post/comment/link changes, and regenerate them regardless on a specific period—I like 1 hour for my RSS widgets—I wouldn’t be able to keep as many widgets as I do right now.

    This is my most valuable plugin, and makes so many of the above possible to keep.

Dropped Plugins and Widgets

  • Custom Query String Reloaded: This allowed me to change the number of posts viewed in particular archive pages, and even to re-order archives from oldest to newest—useful if, say, I were actually writing serial fiction in this blog. It might be useful for my serial articles—the Hugo Awards category, for instance—but I already have In Series above to give readers more efficient navigation on each post. Nice, but not needed, and added a bit in rendering time—and some custom queries are more expensive than others, especially if you’re doing category exclusion.

  • Excerpt Editor: Useful for going through my posts and editing the excerpts without having to actually load every post, and/or automatically generating excerpts by word rather than by individual characters. In the end, I didn’t use it, and anyways didn’t like my date archives or category archives or even tag archives only generating excerpts (I figure people like to read through my day archives instead of slowly clicking on every Read More link that excerpts generate).

  • Genki Announcement:: Cute. It can automatically add an announcement to the top of every page, and can time its announcements. In the end I didn’t need the timing, and stopped making announcements (I could just use a Text Widget for that).

  • Lightbox 2: More HTML and Javascript, not enough benefit (S∂ is not a photo blog), and can’t do Flickr images anyways, which I’m going to need to store all future images on because I’ll otherwise easily run out of disk page.

  • MintPopularPostsWP: Meh. Popular posts are expensive to render in the sidebar, no matter if you use this or wPopularity/Popularity Contest. It’s slightly less expensive than the Popularity plugins, because it doesn’t hit the database again for every post/page/archives load (I mean, Mint already does that for me, and more efficiently too). In the end, I didn’t use and it was too expensive.

  • Multi-level Navigation Plugin: Dynamic Javascript dropdown menus. Very meh for me, because while it generates category, page, and blogroll menus for you, and thus results in a compact view of your site, you can’t use the WP Widget Cache on them, so the thing ends up being very expensive. And plus, more Javascript is loaded into someone’s browser, and in the end it just wasn’t worth it.

  • Recent Comments (built-in): And also any of the extended recent comments plugins. It’s just the way my blog is and how I write: neither attracts huge amounts of comments, nor a constant trickle of comments (I’m thinking of replacing that comments balloon with a category icon or something).

  • Recent Posts (built-in): And also any of the extended recent posts plugins. See “Miscellaneous Replacements” below, because how I chose to replace this is a bit special.

  • SRG Clean Archives: There are efficient ways to parse short codes (see KG Archives above) and then there are grossly inefficient ways to parse short codes. SRG Clean Archives just about wipes out the time it saves by caching its archive output by the time it takes to parse through every single post and page looking for its short code, quadrupling page generation time.

  • Star Rating for Reviews: Shortcode for little stars, and it can store and generate a list of your recent reviews and the little stars. I don’t actually use little stars for my reviews anymore, so I dropped it. A shame, because I did like the little stars….

  • Subscribe to Comments: Again, this isn’t a comment-heavy blog, and since WordPress has a per-post comments RSS, I decided to drop this plugin for my sanity (and the sanity of not sending email out all over the place). And since Making Light makes use of the comments RSS and also included a link to an explanation of RSS, I decided to do the same thing.

  • Theme Test Drive: I’m not changing my theme around anymore, but it sits in the wings in case I need to. Otherwise it adds another database query as it wonders whether to load the theme page for the user or the admin or if it’s on at all, which I didn’t need anymore.

  • WordPress Mobile Edition: Number of Mobile visitors: 2 over the last four months. If this site ever gets popular I’ll reconsider.

  • WordPress Super Cache: My site gets so few visitors that this actually increases their page rendering time on average. (It takes some extra time to generate the cached page if they hit that limit, and there are so few of them that the ratio is of course bad). Plus, site renders here in 0.5 seconds and typically less, and there’s nothing I can do with respect to the already gzip’d output people get to render on their browser, which would be the same in either case, so it’s a wash. Also, the Super Cache, either on or half-on, isn’t compatible with some of my more useful plugins (Search Unleashed comes to mind).

    I’m still keeping it around, though disabled, because its lock-down mode will be useful in the small chance this site ever ends up on the Digg front page.

  • wPopularity or Popularity Contest: I have Mint, and they’re extra expensive (an extra write query on every post or page view to multiple tables) and so are their widgets/PHP functions that would be a bit more useful if I wanted to display Popular Posts. But they definitely increased database queries and thus page renders to 5 seconds on the user side. Not for me, sadly.

  • Yet Another Related Posts Plugin: I like related posts, but it adds more queries on read, plus it becomes really annoying on my In Series articles (it repeatedly relates the other articles in the series to each other, which is nice but really repetitive).

There were more, but I deleted them a while ago even before I wanted to speed my pages up.

Dropped Javascript Badges, Widgets, and Miscellaneous

Javascript is annoying because it adds execution time and, on page load, doesn’t actually execute separate widgets in parallel, unless you add iframes, in which case you have a whole set of other problems (bearable for some widgets, less so for others, especially when they depend on your stylesheet for rendering).

A bit of Javascript can be good (for instance, website metrics, as long as it doesn’t get in the way much, and compressed, tabbed widgets and Lightbox if you’re a photo blog that doesn’t pull from Flickr), but it’s easy to have too much of it.

  • Twitter Badges: Javascript that hits Twitter and pulls your tweets. It doesn’t cache. Twitter limits how many times you can access their API per hour. Not a great combination.

    Replaced with Twitter Tools.

  • Google Reader Web Clips: They’re nice, since you can have a separate clip for each tag you use for your shared reader items ((For more information, see Google’s FAQ on sharing. Very quick to do while you’re reading.)) It’s also very easy to share items when you’re surfing in Google Reader. Unfortunately, it’s Javascript sometimes it doesn’t finish quickly. That’s really not good.

    There are various ways to replace the combined functionality of bookmark/sharing and little widget for your blog. My favorite is StumbleUpon (even if I have to actually visit the entry to bookmark it—increasing visitor counts isn’t a bad price to pay if I like an article enough to bookmark it) combined with the RSS widget for my StumbleUpon “reviews” RSS. ((You can see the RSS links on the right of your StumbleUpon home page.))

    Since I use WP Widget Cache, my RSS widgets are all cached, thus winning where not-pulling-data-from-remote-sites-all-the-time area. Also, my comments can be shown on the page, along with dates that I bookmarked things. I treat my StumbleUpon blog as, well, a blog exclusively for short entries about links. Avoids creating trivial linkspam posts on the main blog, and puts them up explicitly on a site geared towards sharing that sort of information. Win.

  • Feedburner Site Stats: No plugin, but it’s Javascript you can add to every post (and multiple times if you wish to a web page) to call out to Feedburner and fetch back information plus a little subscribe link and any website Feed Flares you may have configured.

    That’s three strikes: 1. Calling out to another website, multiple times on my front page and date/tag/category archives; 2. Javascript called repeatedly; 3. I already have Sociable, so Feed Flares is a bit redundant. Add a fourth strike that Feedburner Site Stats aren’t reliable, and it loses out to Mint and almost everything else.

    So I replaced the Feedburner Site Stats with a hard-coded link to my Feedburner RSS. This is as easy as adding the Feedburner Site Stats in the first place, e.g., you have to edit multiple files in your WordPress theme. Sigh.

Miscellaneous Replacement

This is a bit special, since it involves replacing the Recent Posts plugin (which adds more queries, especially non-context-sensitive and thus extraneous ones in date/category/tag archives) with code that generates a “page summary” similar to the one available on some LiveJournal themes. ((My current theme on LJ as of this time does not include a page summary, and I miss it.)) It lists, in a small space, every post on the page, nice because I so often stick full-length posts on the page ((Because it annoys people to click Read More unless you’ve to something really interesting behind it. Sadly, even in a very focused blog on meta-blogging, this is often not the case.)).

As an extra plus, the links in the page summary simply jump to that article on the same page, rather than taking extra time to visit the article page. This isn’t a very comment-heavy blog, after all. Despite that, it does include the number of comments in square brackets per post if there are any.

The best bit is that it doesn’t require extra queries.

This little box takes code, which I should post one day. Or I might write a plugin widget for people to use, since I didn’t see anything similar around the last time I checked (which is often).

6 thoughts on “Speeding Up Your WordPress Blog

  1. hmm, couple of interesting plugins here. I’ve been looking for a way to re-order the blogroll thanks.

    The main reason I removed Theme Driver plugin is because it became redundant with WP 2.6, which added an automatic theme preview on the backend and does a better job of it than the plugin did.
    Which version of wordpress are you on?

  2. I’ll probably keep Theme Test Drive out of the way, deactivated but in the wings. It lets me work with a theme, operating every part, while my users continue to see the old and working theme. WP Theme Preview doesn’t let you do that.

    Currently I’m on 2.6.2, but shortly I’ll be using the automatic upgrade to hit 2.6.3. :)

  3. Interesting to hear our plugin doesn’t work with the widget cache plugin.

    The javascript is only used for IE6 and less or if you want animated dropdowns.

  4. Hi Ryan!

    With regards to the Javascript and Multi-Level Navigation: Ah, you’re right; for the rest of the browsers and versions, the CSS is enough.

    With regards to widget cache: Widget cache only works on actual widgets. PHP code not in a widget will not get cached.

    Now, you can get around this with Multi-Level Navigation:

    1. Add another sidebar in the theme’s functions.php

    2. Insert PHP code to include sidebar in the theme’s header.php

    3. Add basic CSS styling to the new sidebar’s HTML so it sits across the top of the theme.

    4. Install Exec-PHP and put a PHP-enabled text widget in this new sidebar that includes the Multi-Level navigation menu php function.

    5. Proceed as normal.

    It was a bit too much for me, unfortunately.

Comments are closed.