1

To give you the context first: Let's say you create a custom plugin by yourself. That plugin has for example:

A) 30 different endpoints / REST calls,

B) adds 15 different admin pages to the wp-admin,

C) enqueues a script specific to every single admin page,

and so on.

To enable the entire functionality of this, I do:

A) 30 different calls to register_rest_route, and hook them to the rest_api_init hook.

B) Load the 15 different admin pages, and hook them to the admin_menu hook.

C) Enqueue all of the page-specific scripts via switch($page_slug) and hook that to the admin_enqueue_scripts hook.

Everything of this works perfectly, which is why won't detail the code any further. Because my question does not really concern code, but the logic of wordpress and hooks under the hood: Currently, the code for A) - C) is written in the main plugin file of my custom plugin, and I've generally learned to do it that way. Meaning, AFAIK, that the entire hookings run on every single page load.

I now wondered: Couldn't you for example hook your 30 endpoints of your REST API only for example via the activation hook of the plugin or similar? And similar for the admin pages?

Just feels odd to me that you're loading the same code, whose output is theoretically a static registration, over and over again in production systems, and this on every single page load.

4
  • 2
    Regarding the plugin activation hook, it runs only upon activating the plugin and not when it's already activated, so no, and for example, just use rest_api_init to register your REST API routes because just like custom post types, they're stored in memory and not the database, otherwise what you asked would be possible at plugin activation. I.e. If for example, WordPress automatically reads custom REST API routes from the database and registers them on page load. But if you show your code (that "repetitively yield the same output"), you might get better responses on structuring your code.
    – Sally CJ
    Aug 6 at 13:40
  • Cheers! By "repetitively yield the same output", I just meant "yield the same effect". That is, for example, registering REST endpoints. But alright, learned now why it's done that way; I supposed some storage in the DB. Cheers!
    – DevelJoe
    Aug 6 at 13:51
  • Just a final note that might help - for example your REST API routes, you could also define them (just the arrays) in a separate PHP file and then include it upon calling register_rest_route(). I.e. Something like $routes = include '/path/to/file.php'; foreach ( $routes as ... ) { register_rest_route( ... ); } That way, the main plugin file would be smaller in size. So you do not necessarily need to use the DB.
    – Sally CJ
    Aug 6 at 14:15
  • Yup, I've indeed started with exactly what you describe a few hours ago! :)
    – DevelJoe
    Aug 6 at 15:43

1 Answer 1

2

Long-running software may be able to register functionality once and leverage those registrations for every connection across the lifetime of the process, but in the case of WordPress (and most of the PHP web software landscape as a whole) the long-running connection management is offloaded to the web server software. WordPress executes from the top for each individual request - so short of implementing a web server extension or standalone process, WordPress extensions cannot really implement or use a common runtime environment shared between requests.

This generally isn't anything to sweat however. WordPress's hook system embodies an event system, and registering even handlers/hooks is a negligible operation - even if you're registering thousands of hooks there's unlikely to be any notable performance overhead, as each is little more than inserting a new item into an array.

The same is mostly true for registrations of other types as well - post types, taxonomies, admin pages, REST routes, etc.

You could store some sort of state in the database - but database interactions add a considerable amount of overhead compared to just recreating the state in code. Loading some sort of stored state would be performing the same work - "pushing the same items to the same arrays" - just with additional work to retrieve them first.

Since WordPress only executes the actions/filters which are relevant to fulfilling the current request, if your registrations and functionality are hooked to the appropriate actions & filters, then they won't execute when they're not needed. For instance, in the course of serving a front-end page request the rest_api_init action will never fire - so your 30 REST route registrations will never execute, and when fulfilling a REST request the wp_enqueue_scripts action will never fire, etc.

PHP does interpret all of the code in a file when it's loaded - so even functions which will never execute will be interpreted. But this too is generally negligible - PHP interpretation is fairly fast, and often getting faster. It is possible to split your code into multiple files and only load them if necessary/use an autoloader to that end - but generally interpreter overhead is not a motivation for doing so. Usually it's just a matter of code organization.

4
  • 1
    Wow thanks for this very detailed answer! Makes me remember about a discussion I had last day where my colleague heavily criticized PHP as being interpreted vs java in terms of performance. But I really feel too that PHP interpretation is getting negligibly fast vs pre-compiled code. Anyway, that's another debate..
    – DevelJoe
    Aug 7 at 0:03
  • Oh, pre-compiled will definitely always win the race, but there are always tricks to squeeze a little more performance out of PHP. Interestingly Facebook's HHVM used to pre-compile PHP to machine code, but the PHP 7 interpreter sometimes still outpaced the compiled code. Then there's the crazy stuff that JavaScript pulls, like optimizing hot code paths on-the-fly. It'll still loose against C in every situation, but it does it with... some sort of hipster style 😎
    – bosco
    Aug 7 at 0:13
  • In short though, I think all too often the debate doesn't factor in whether or not an application demands the absolute best-case performance. Runtime speed and efficiency is awesome, sure, but in so many situations they are not the most important factors - sacrificing a little runtime speed for a better developer experience or reduction in development time is often a worthwhile trade/business decision, especially when you're not building for large-scale traffic or data.
    – bosco
    Aug 7 at 0:29
  • 1
    Couldn't agree more! And interesting the thing with Facebook, a nice example of people using code of a language thinking they're smarter than the original minds behind the language itself :D
    – DevelJoe
    Aug 7 at 0:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.