Why WordPress REST Performance Sucks

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.

Why?

WordPress is NOT built around performance.   WordPress is built on two core tenets – ALWAYS support legacy users at all costs.    Be extensible.

Legacy Support

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.

Extensibility

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

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.

Simple, right?

WordPress REST

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.

AJAX Too

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.

if ( 
  defined( 'DOING_AJAX' ) && DOING_AJAX && 
  ! empty( $_POST[ 'action' ] ) &&  ( $_POST[ 'action' ] === 'heartbeat' ) 
) return;

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?

Maybe Gutenburg,  the core of the forthcoming WordPress 5.0 release, will have shone some light on this limitation as it is a reactive JavaScript app — but something tells me the focus is more on “shiny new web interface” than performance.    Hopefully that changes if Matt truly wants to make WordPress a viable contender as an application framework and not just another web presence platform.

3 thoughts on “Why WordPress REST Performance Sucks

  1. I am in the process of eliminating wordpress from all of the sites I manage for this reason. They seem to be more interested in surface level issues than fixing the deep architecture problems that plague the system. In addition to the problems noted, the database schema is a disaster.

    The new GUI editor stuff is something that I explicitly don’t want in a CMS, and gave me the impetus to move. I don’t find the wordpress stock plug ins very useful as many are abandoned, are of questionable quality, or are overcomplicated ‘do everything’ systems that should be broken into smaller components.

    1. Bypassing WordPress is certainly faster, but you forego a lot of the flexibility and single point of entry benefits of using WordPress in the first place. You gain performance but open up more maintenance issues and potential security issues in this type of approach. The cache idea limits exposure, but it is one more piece outside of the main web app that needs to be managed and maintained. Finding the right balance between a custom app and off-the-shelf is always a trick. Knowing how to set that balance and the trade-offs involved is a big reason why having a skilled web development professional on the team versus a basic “webmaster” or typical “I can install plugins so I’m a WordPress Developer” is critical to the success of an online business venture.

Leave a Reply

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