Excluding WordPress plugins from loading for specific AJAX requests

TL;DR – Every time an AJAX request is served by WordPress, all of WordPress core, the active theme, and all the active plugins are loaded. We can cut down on that overhead by excluding specific plugins from loading for specific requests by employing a Must Use plugin.

One of the standout features of WordPress is its ability to be extended to do just about anything. The flexibility WordPress provides is great but can also lead to a number of compatibility problems. If you’ve ever released a theme or plugin, free or paid, I’m sure you’ve experienced this. Or even if you’ve simply used lots of themes and plugins, you’ve probably had compatibility issues.

We’ve experienced this firsthand with WP Migrate DB Pro. Themes and plugins conflicting with migrations makes up the majority of our support requests. Some plugins come up so often, that we’ve started publishing a list of plugins known to conflict with WP Migrate DB Pro.

In the past we tried to diagnose these plugin conflicts on a case to case basis but often found that getting around the issue was not possible. And so we had to ask our customers to deactivate the plugin before running a migration. Far from ideal and an unacceptable customer experience as far as we’re concerned.

So we decided to attack the problem a little more aggressively. How could we skirt these plugins?

Version 1.4 introduces a new setting that allows you to control which WordPress plugins are loaded for requests made by WP Migrate DB Pro. It’s the ability to exclude plugins from loading in a migration request.

Example

Let’s say you have these plugins installed:

  • Easy Digital Downloads
  • Envira Gallery
  • Bad Behavior
  • SearchWP
  • WordPress SEO
  • WP Migrate DB Pro

You are having trouble with your migration and after checking our documentation, you see that Bad Behaviour is in the list of plugins known to conflict with migrations. So you do the following:

  1. Visit the Settings tab in WP Migrate DB Pro
  2. Check the checkbox “Improve performance and reliability by not loading the following plugins for migration requests” and confirm the warning
  3. Select Bad Behavior in the list

Now when a request is made it looks like this:

  1. We check if the request is a WP Migrate DB Pro migration request and if not, we let WordPress process the page request as usual
  2. If it is, we load the plugin blacklist
  3. All plugins are loaded except Bad Behavior
  4. WordPress continues to process the page request as usual

It is important to note that we only exclude plugins from loading once we have determined that the request is a migration request from WP Migrate DB Pro. Bad Behavior will still be loaded for any other requests.

Performance

But why only exclude Bad Behavior from loading? Why not exclude Easy Digital Downloads, Envira Gallery, SearchWP, and WordPress SEO as well? After all, these plugins don’t operate on migration requests. In fact, although these plugins are very well coded, just loading them does use up some memory. Other plugins that are not so well coded may use up a ton of memory just by loading them.

We recommend excluding all plugins from loading for migration requests. It won’t hurt and could result in a big improvement in the performance of your migrations. It’s a no-brainer really.

How Does This Work Exactly?

A regular WordPress plugin isn’t able to control which plugins are loaded and which aren’t. So, when you check the checkbox “Improve performance and reliability by not loading the following plugins for migration requests” we ask if you’re ok with installing a Must Use (MU) plugin to enable this functionality. (Similarly, the MU plugin is deleted upon unchecking the checkbox.)

mu-confirmation

MU plugins are very different from regular WordPress plugins. They are installed in a special /wp-content/mu-plugins/ folder separate from regular plugins. They are active for as long as they are in that folder. To deactivate them you need to remove them from that folder. An MU plugin is also executed before regular plugins are loaded.

This is why we use an MU plugin here. We can get ahead of the loading of regular plugins and control which ones are loaded.

Our MU plugin in this case consists of a single function:

function wpmdbc_exclude_plugins( $plugins ) {
	if ( !defined( 'DOING_AJAX' ) || !DOING_AJAX || !isset( $_POST['action'] ) || false === strpos( $_POST['action'], 'wpmdb' ) ) return $plugins;
	$wpmdb_settings = get_option( 'wpmdb_settings' );
	if ( !empty( $wpmdb_settings['blacklist_plugins'] ) ) {
		$blacklist_plugins = array_flip( $wpmdb_settings['blacklist_plugins'] );
	}
	foreach( $plugins as $key => $plugin ) {
		if ( false !== strpos( $plugin, 'wp-migrate-db-pro' ) || !isset( $blacklist_plugins[$plugin] ) ) continue;
		unset( $plugins[$key] );
	}
	return $plugins;
}
add_filter( 'option_active_plugins', 'wpmdbc_exclude_plugins' );

As you can see we’re hooking into a filter. So when get_option( 'active_plugins' ); is called, this function will be executed and may modify which plugins are active.

The first conditional statement ensures that we’re processing a WP Migrate DB Pro AJAX request, and if not we bail, letting WordPress serve the request as usual, loading all the active plugins.

The second part of the function loops through the list of active plugins and checks a couple of conditions. First, we ensure that the plugin is not WP Migrate DB Pro or one of its associated addons. We want those to be loaded. Then we check whether the plugin is in our blacklist of plugins to exclude. If it is, we simply remove it from the list of active plugins, preventing it from being loaded when WordPress loads active plugins.

This feature will be available in version 1.4 of WP Migrate DB Pro. If you’d like early access, sign up for the beta mailing list.

I’m really proud of our team for coming up with this solution and I think it could solve some problems for other plugins and themes that make heavy use of AJAX requests and want to improve performance. We’d love to hear your thoughts on this solution. Will you be using it? For what?

About the Author

Brad Touesnard

As founder of Delicious Brains Inc., Brad wears many hats; from coding and design, to marketing and partnerships. Before starting Delicious Brains, Brad was a busy freelance web developer, specializing in front-end development.

  • harishchouhan

    That’s awesome news Brad. have faced this issue myself few times.

  • Great news! I’ve also run into this problem a few times. Looks like another solid update.

  • Aron

    So thats why I had issues while having Rev Slider installed. Good to know. Any ETA on release? Thanks for the hard work btw.

  • donkeyjong

    Nice use of the MU plugin! Really, as you say, its a no brainer.. I will definitely blacklist all plugins when this feature is live. Anything to cut down on the waiting 🙂

  • Jesper Søholm

    This sounds really good.
    Could you perhaps give some examples on plugins that you wouldn’t want to disable during migration, please?! (Just to get a better understanding of the process of migration.) Would, for instance, something like the Custom Post Type UI plugin be necessary for a successful migration?

  • lpdechow

    Sounds like a great solution.
    Will the plugin re-enable the plugins after the migration?

  • Excellent addition to the already five stars features.

  • Darshan Sawardekar

    Nice use of the ‘option_action_plugins’ filter.

    I am curious as to what makes up the Bad Behaviour plugin. Is there something that plugins should do to work better with WP Migrate DB. Or is it a case of not doing something to avoid interfering with it?

  • lkraav

    I def like this approach. I know people are looking how to do performant AJAX on WP like it’s the Holy Grail and this looks like a good first step into my own path towards.

  • This is great! I just needed this feature because I was getting an AJAX error when I tried to do a migration on a particular site. I don’t know which plugin was causing the problem, but I used this feature to disable all plugins during the migration process it worked like a charm.

    Is this in the documentation for the plugin yet? I almost missed it!

  • Mark

    Hi, all this is quite foreign language for me so if someone can verify something for me that would be great; I have a WP theme that has AJAX as part of it, however, the AJAX interferer with two plugins (TwentyTwenty and Jetpack Sharing), Would this MU Plugin help?

    TwentyTwent does not laod when first opening page )post) and the page has to be refresh for the plugin to show. The Jetpack Share plugin is different, when clicking on an icon (Facebook, Google+ etc) the site disappears and it is needed to reload it again,