Turbo Charging the Loop

Turbo
The WP Crowd

Andrew Killen

contributor
BIO
Published: May 12, 2016
Topics:

WordPress uses “the Loop” to create content it gets from the database. It’s used all over the place, be that within the standard theme files such as index.php, single.php, archive.php etc etc etc. Often as coders we use the loop to get information using WP_Query(); take the below example which is taken from a Widget that gets the latest 5 posts, excluding the current post (if there is one);

Yes you’ve seen it a million times, or something similar. But while you may think that this is a great use to your coding skill and gets the required result, there are in fact two simple things you can do to vastly improve the speed of the loop.

Reducing the demands on WordPress WP_Query

WP_Query is a class and creates an object. In the object it creates many things that are not always necessary. These are created automatically unless you tell it not to. The two quick things we can get it to not do is work out the total count of items that match the query, so not to workout the pagination, and to not do anything with the postmeta as its not going to be used.

By just adding two extra arguments it reduces the overheads on the database, so will reply with a faster query than the previous one.

Taking a closer look at the two changes

‘no_found_rows’ => false is used to tell WP_Query not to look for all of the possible rows that meet the query, which is mostly used when doing pagination. ie. WP_Query finds 500 rows that meet the query, at 5 posts per page there would be 100 pages of posts in the possible pagination. However, by making this false, it tells WordPress not to make this secondary database query to get the row count.

‘update_post_meta_cache’ => false is used to tell WP_Query that it should not update the cache of the post meta of each post ID. Every time a post is called from the db WP_Query will try to cache the post meta so that it is much quicker to get when using get_post_meta(). But as in the loop example above, there is no need for this as it is does not use the post meta at all to display the information needed. So by setting it to false, it tells WordPress to ignore that activity, making the loop quicker.

Exclude the existing post at the right place

Although I was always told that its always quicker to get data from the database with a query than it is to work out what is needed later in code, its not always true. In the case of post__not_in its actually quicker to ask for more posts and exclude the ones you have until you have the right number of posts in the loop to display.

The reason that this is quicker is that we’re only asking for the bottom X number of posts (5 + count of array of posts we don’t want), so in this example this will be just 6 (which is not quicker the php way all the time, it depends on the size of the db, number of posts etc. remember its just an example!), but of course this could be much higher if you’re using this as part of an ajax call to get the next set of posts, excluding the last ones. Its much more difficult for the database server to check for the last 5 posts, but make sure that it does not contain the ones we don’t want.

Putting this in to practice looks like this:

Small change equals big improvements

In the world where we are trying to return to the client in less than 200ms so that google gives us the thumbs up and thinks our site is fast, this can shave off many of those extra milliseconds. These tests were performed on a mac book pro 8GB mem, SSD and i5 processor, using Apache / php5.6.

descriptionfirst run (in ms)second run (in ms)
Standard method6.63185119628916.3347816467285
Excluding extras from WP_Query5.22494316101075.3169727325439
Excluding extras and not using post__not_in5.32317161560065.5720806121826

please note, this was making an exclude of only 1 post, this may work better in some cases going direct to the db to make the query, sometimes it works better with the exclude. Depends on the db size, and number of posts you are excluding

TL;DR

There are some ways to shave off those milliseconds from the loop. Firstly reducing the amount of information that must be processed by WP_Query, and secondly by changing the way the loop works to perform the exclude of posts in it rather than with the database query.

Get the latest from The WP Crowd

15
Leave a Reply

avatar
7 Comment threads
8 Thread replies
0 Followers
 
Most reacted comment
Hottest comment thread
4 Comment authors
Make Your Site Faster: It Matters... A Lot - The WP Crowd The WP CrowdandykillenAhmad AwaisSallie GoetschNick Ciske Recent comment authors

This site uses Akismet to reduce spam. Learn how your comment data is processed.

newest oldest
Nick Ciske
Guest
Nick Ciske

Seems like you could potentially filter the query arguments and if it’s not the main query make an assumption and set these arguments to get a side wide speed up effect…

andykillen
Guest
andykillen

In theory yes, but I think it can only apply to some websites, and might have bad knock-on effects with other peoples plugins.

If your site is closely under your control then I think you can, if you rely on anyone else’s code then you are at risk of getting spurious errors/problems.

I really considered this when making this post, and also seeing what transients might mean to the equations, but the variables are too great to give sound advice.

Ahmad Awais
Guest

Nice one, Andrew! Maybe you can edit the gists and and add <?php at the very top so that GitHub can recognize the PHP language and color the syntax.

andykillen
Guest
andykillen

what can I add? looks like your save got cut off

Ahmad Awais
Guest

Add the starting tag for PHP so that it can highlight the syntax. I am talking about adding < ? php (intentionally added the spaces) at the top.

Ahmad Awais
Guest

Nice one, Andrew! Maybe you can edit the gists and and add <?php at the very top so that GitHub can recognize the PHP language and color the syntax.

andykillen
Guest
andykillen

what can I add? looks like your save got cut off

Ahmad Awais
Guest

Add the starting tag for PHP so that it can highlight the syntax. I am talking about adding < ? php (intentionally added the spaces) at the top.

Sallie Goetsch
Guest
Sallie Goetsch

If you turn off pagination, how do you get to the older posts? Or are you assuming that in this situation you only want to see the first 5?

andykillen
Guest
andykillen

yes, this is when you for example want to only see X number of posts. So pretty much ideal for many widgets that use WP_Query()

Sallie Goetsch
Guest
Sallie Goetsch

If you turn off pagination, how do you get to the older posts? Or are you assuming that in this situation you only want to see the first 5?

andykillen
Guest
andykillen

yes, this is when you for example want to only see X number of posts. So pretty much ideal for many widgets that use WP_Query()

trackback

[…] After patching this guy up our bounce rate dropped 20% almost instantly and sales nearly doubled in the first week.  Speed Matters. For more information on speeding up your site before sure to check out our article on Turbo Charging the Loop. […]

trackback

[…] After patching this guy up our bounce rate dropped 20% almost instantly and sales nearly doubled in the first week.  Speed Matters. For more information on speeding up your site before sure to check out our article on Turbo Charging the Loop. […]