WordPress REST performance sucks. There, I said it. Not because I dislike WordPress — in fact I think it is the best open source web application we have seen thus far. It is a great piece of technology. It even has the potential to be a great web application framework — in fact I use it for the Store Locator Plus managed service, MySLP.
However, unless you are in 100% complete control of every component in the system you are going to very likely end up with an underperforming over-burdened web service if you build your tech on typical WordPress components. Even the highly customized MySLP service is 5-10x slower than it would be if it was build on a completely customized application stack outside of WordPress.
WordPress is NOT built around performance. WordPress is built on two core tenants – ALWAYS support legacy users at all costs. Be extensible.
This is only a small reason why WordPress performance suffers in most applications. Thankfully WordPress runs great in PHP7 which help mitigate a big chunk of the performance problems in the underlying technology. Unfortunately WordPress still supports PHP 5.2 and MANY plugins and themes are written to do the same lest they risk losing part of the market. This means they do not take advantage of language constructs in later versions of PHP that are designed with performance in mind.
However the bigger issue is the HUNDREDS of action hooks, filters, callbacks, and deprecated code that is not only loaded into memory but often processed hundreds if not thousands of times on every page load. If WordPress were to drop legacy support for deprecated hooks, filters, functions, and other “cruft” that has built up over years it would eliminate 10-20% of function and memory management overhead from the 70% of web servers running older themes on the PHP5 stack on WordPress.
Sure, the library of 55,000 WordPress plugins would potentially drop by half, but let’s be real — less than half those plugins are actually in use. Does anyone really want to be using plugins built on deprecated methods anyway? Consumers would probably prefer less than 3,500 choices of Facebook plugins – a side bonus of dropping legacy support.
This is a far bigger issue. WordPress is extremely flexible. This design, made possible by those hooks, is the stroke of genius that made WordPress the success story it is today. A well-document stack of action hooks made it easy to write plugins and themes that could take over MOST of WordPress creating thousands of variations of website all running on the same core engine. It is truly awesome.
However it sucks for high performance web applications. This very extensibility combined with the “anyone can publish a WordPress plugin or theme” means that MOST of your typical WordPress sites are a mix of great code and complete shit.
Having worked on custom SaaS applications, eCommerce sites, and vendor services built solely on WordPress over the past year I can tell you that poor performance is the standard, not the exception. This is because NOBODY is writing code that is designed with REST or even AJAX performance in mind.
Let me explain in over-simplified terms…
REST is a standard for communication between web applications. In its simplest form an application can make a request for information from a REST-enabled application. That application listens for the incoming request and sends back the information. It is meant to be a lightweight simple process.
Let’s describe a simple example —
You want to know what is on the menu at a restaurant including the specials. You call the restaurant. The “listener” answers and you ask them to email you a copy of the menu and today’s specials”. They grab a copy of the PDF, ask the kitchen manager what today’s specials, and write you an email — a few second later your phone pings you with the information, you thank them and hang up.
WordPress has touted the built-in REST listener to make it a “good web citizen” that makes it easy to share information stored within a WordPress site.
But there is a problem. It goes back to all that extensibility. It is extremely rare that a plugin or theme author actually pays attention to what WordPress is doing when they load up their “super awesome, everyone should have it” code. 95% of plugins and themes load up their code all the time, every time, no matter what. Even worse, 80% of the plugins and themes are procedural code – meaning they load literally “every single possible function always”.
So what does that mean for our simple REST request to get today’s menu and specials?
You call the WordPress Cafe and ask the “listener” to email you a copy of the menu and today’s specials”. Instead of the scenario above you get this —
They go to grab a copy of the PDF, but the printing company that creates the PDF stops them on the way. They ask them if they want to change any colors of fonts on the menu. Do you want it in mobile of web format? What font face? Twenty questions later they hand over a menu. As soon as our “listener” turns around the historian asks if they want to make a written record of the request. The cashier overhears the conversation and says “hold on, there may be some rate changes with the credit card company — we may need to change our prices” and they hold up our listener while they call the credit card company.
The entire time our listener is thinking “I just need a copy of the freakin’ menu to give to a customer”. But EVERYONE ELSE that has anything to do with the business gets involved. The kitchen manager is checking inventory to make sure everything on the menu can be made should the customer ever call back to place an order. The hostess is checking to make sure there are seats available even though the customer may never show up and almost certainly is ordering take-out if asking for a menu over the phone.
30 minutes later our “listener” sends the very same menu and specials email that was sent in our previous example, but after far more hassle. What should have been a 3-second process takes 30 minutes.
This is WordPress as a REST service.
There are ways to simplify the process and make WordPress faster. Sadly very few plugin and theme authors care to check what WordPress is doing. While it would be fairly easy to do things like “don’t get involved if I have nothing to contribute”, that is not how most WordPress plugins and themes are written. And in the case of REST requests, WordPress does not provide a built-in mechanism to test for “REST processing” or the state of the request.
While you could argue “well REST is new, people haven’t caught up yet”, it is not THAT new. It has been around for years. AJAX, has been in the product far longer.
Did you know WordPress runs an AJAX request every 15 seconds? It is called the WordPress “heartbeat”. It is useful for some automated tasks on a WordPress site.
Do you know how many plugins actually do anything when a heartbeat request comes in? Less than 5%. Do you know how many LOOK for the heartbeat and exit immediately if they KNOW they have zero influence on heartbeat processes? I know of only one — Store Locator Plus.
defined( 'DOING_AJAX' ) && DOING_AJAX &&
! empty( $_POST[ 'action' ] ) && ( $_POST[ 'action' ] === 'heartbeat' )
Performance Is An Afterthought
Sadly performance is an afterthought for most WordPress developers. When they do think about performance it is usually only in the context of “how fast is my stuff” — not “am I slowing down someone else’s stuff for no good reason”. Many do not employ even the most basic plugin performance tricks.
This is why I often find things like WooCommerce and many of the WooCommerce plugins loading things like CSS stylesheet processing and image management on a REST request that has NOTHING TO DO with user interface styles or images. Or why BuddyPress loads a huge global stack of “just in case they need them” methods and functions – to the tune of 8,000+ excess init() calls that load code that will never be needed when asking for nothing but a list of products in the WooCommerce database.
When my clients ask why a simple REST request is taking 3 seconds to respond versus the instant response times of competing sites I often have to explain “WordPress, it is not a performance app”. It could be, but by not having a set of Best Practices or providing the internal tooling necessary to allow third-party developers to create performance-centric apps it is relegated to second-class status when it comes to modern complex web applications.
A Glimmer Of Hope?