WordPress.org

Make WordPress Core

Opened 11 months ago

Last modified 2 months ago

#41346 reviewing feature request

Introduce a hook for individual plugin loaded

Reported by: Rarst Owned by: johnbillion
Milestone: 5.0 Priority: normal
Severity: normal Version:
Component: Plugins Keywords: has-patch
Focuses: performance Cc:

Description

The current plugin load during core boot is essentially a series of include firing:

// Load active plugins.
foreach ( wp_get_active_and_valid_plugins() as $plugin ) {
        wp_register_plugin_realpath( $plugin );
        include_once( $plugin );
}
unset( $plugin );

Currently it is exceptionally hard to fire off arbitrary code between these includes. The closest I got over years is the following code, which I consider highly unstable: https://gist.github.com/Rarst/c32575ffc26df59a45c0

Distinguishing between load events of individual plugins is highly desirable for performance troubleshooting. In current state it is defacto impossible to troubleshoot with PHP code, requiring manual toggling of plugins or low level PHP profiler set up.

Adding individual plugin load event will make it much easier to profile and diagnose performance issues at this load stage.

Can be as simple as:

        include_once( $plugin );
        do_action( 'plugin_loaded', $plugin );

Attachments (1)

41346.diff (395 bytes) - added by schlessera 10 months ago.
Simplest solution to the issue

Download all attachments as: .zip

Change History (6)

#1 @schlessera
11 months ago

Why not go all in and make it a flexible system that can be the basis of additional work?

// Pre action to allow for timing hooks to be set,
// debugging information to be initialized, etc...
// Could also allow for the loading to be skipped.
// Dangerous hook, though, needs careful consideration.
$should_load = apply_filters( 'pre_plugin_loaded', $plugin );

// Actually load the plugin.
$should_load && include_once( $plugin );

// Post hook to catch timings, debugging state, etc...
do_action( 'post_plugin_loaded', $plugin );

// Named hook to actually have a proper chance of building a simple
// dependency resolution mechanism.
$plugin_slug = some_method_to_efficiently_retrieve_plugin_slug();
do_action( "plugin_loaded_{$plugin_slug}", $plugin );

As an example for the usefulness of the named hook, such a very simple system has been used in WP_CLI to automatically resolve dependencies between commands. The basic principle would be applicable as well here. If a plugin knows it depends on jetpack, it can check whether jetpack is available when loading, and if not, it can postpone its loading by attaching its own loading process onto the plugin_loaded_jetpack hook.

#2 @Rarst
11 months ago

Preventing plugins from load is already possible (if not too cleanly) by filtering the option with active list.

To be clear while dependencies are definitely a problematic area, my prime focus with this suggestions is performance troubleshooting and enabling something that is both valuable and low hanging for it.

I don't see (at the moment) anything critical for inter–plugin interactions that cannot be handled on long established plugins_loaded hook, signifying complete load of them.

@schlessera
10 months ago

Simplest solution to the issue

#3 @schlessera
10 months ago

  • Keywords has-patch added

I uploaded a very simple patch that immediately solves the raised issue.

As regards to what I had suggested as an enhancement, I will work on a bigger issue/patch that makes one proposal of solving plugin interdependencies, just to show how that could potentially work.

#4 @johnbillion
4 months ago

  • Milestone changed from Awaiting Review to 5.0
  • Owner set to johnbillion
  • Status changed from new to reviewing
  • Version 4.9 deleted

#5 @schlessera
2 months ago

I've created a new ticket for the suggestion I made earlier in here at #43882. This way, discussing the more elaborate mechanism does not block us from just committing the simple fix we have in here.

Note: See TracTickets for help on using tickets.