Each email sent from your store takes times to compile and to send. Whenever an order transitions to another status, when products are running low on stock, when passwords are changed, new users register, an order is placed in the checkout, etc. emails are sent to the customer, to the admin in the worst case to both.

Since each email can take somewhere between 1-3 seconds to send, you might end up with a degraded user experience, without knowing why this is happening. This is especially annoying when a customer is entering their payment information in your WooCommerce checkout and is expecting to see an order confirmation page. But hey, WooCommerce sends a order confirmation to the customer himself, another order notification to the site admin, a third email to notify that stock is running low, maybe even a fourth email with payment instructions on specific pre payment methods. If you happen to register the new customer in your checkout, there even might be more emails being queued up to being sent. And whoops your customer is already waiting for 15-20 secs, to see a simple order confirmation page.

We need to do 2 things to fix this standard behaviour, first we want to reducing the number of emails sent by deactivating everything that’s not essential or of real benefit to you. Of course performance depends on many factors: How fast is my transactional email provider? Am I sending emails from my server or via 3rd party email service?

Step 1: Deactivate non-essential WordPress emails

Use the excellent and simple Manage Notifications Emails Plugin to disable all non essential emails (and ugly because they are non-HTML Emails) WordPress sends by default.

composer require wpackagist-plugin/manage-notification-emails

As you can see in my screenshot, I deactivated all non-essential notifications. We will only keep those password reset emails activated.

Step 2: Deactivate non-essential WooCommerce emails

WooCommerce Email Settings

Disable as many non-essential emails under WooCommerce -> Settings -> Emails. For example: Why send a order confirmation and a duplicate admin notification if you could simply BCC the admin in the order confirmation.

Send emails asynchronously with Scheduled Actions

Sending out emails is important, but we don’t want the customer to wait for emails being sent out in the background. Which is why we want to alter WordPress’s mailing functionality to send out emails asynchronously – not when the user interacts with our site.

This will improve the site performance and will use WordPress scheduled actions logic to send out the email at a later time. In order to not confuse our customers we will send out emails once a minute. The code below is taken from an article on Stackexchange How to make WordPress Email Async.

wordpress/wp-content/themes/storefront-child/functions.phpif ( ! defined( 'DOING_CRON' ) || ( defined( 'DOING_CRON' ) && ! DOING_CRON ) ) {    function wp_mail() {        $args = func_get_args(); // Get the args passed to the wp_mail function        $args[] = mt_rand(); // append dummy argument to make sure action is unique        wp_schedule_single_event( time() + 5, 'cron_send_mail', $args );    }}function example_cron_send_mail() {    $args = func_get_args();    array_pop( $args ); // remove dummy argument appended earlier    call_user_func_array( 'wp_mail', $args );}add_action( 'cron_send_mail', 'example_cron_send_mail', 10, 10 );

What this does is to overwrite WordPress pluggable wp_mail() function when an email is sent, and add it to the scheduled actions queue. Now when these scheduled actions are processed it uses WordPress’s native wp_mail() function again and sends them.

While this is already an improvement, the code is listed here for reference only. In part 14 “Replacing WordPress Cron and Scheduled Actions with a real cronjob” we will deactivate the scheduled actions completely, so please consider installing the following plugin instead.

Send emails asynchronously with a Plugin and Cronjob (recommended)

So let’s write a standalone, custom-made plugin for this purpose. What are the benefits?

  • we can turn off WordPress’s fake cron & scheduled actions completely, and still send out emails asynchronously.
  • we will store each email to the database, which gives us an email, an overview of all the emails sent from our store.
  • it allows us to easily resend an email (with a different provider) in case a customer reports a missing email.
  • it gives you the control to decide which email provider shall be used on a per-email & per-domain level.
  • and most important we will boost the performance of an online stores most important pages: the checkout, and thank you pages.

Having all of these requirements in mind, here is the plugin: WP Async Mailer. In its first release it supports sending emails with Gmail, Mailgun, Yahoo, Microsoft, SMTP, and PHP mail() and offers using the respective providers SMTP or API integrations. Although sending queued emails has been intended to be done by a real cronjob, it also offers the use of WordPress Scheduled Actions for those cases where you cannot create cronjobs. But then you probably wouldn’t be reading articles written for web professionals in the first place.

Continue to part 7 of this tutorial series: Optimising Frontend Resources with Perfmatters & Grunt.