Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

Performance, caching and launch

A shop that worked well with ten products on a local machine meets real load on a production server: hundreds of orders, a cache, mail, a payment service. Three things are checked before launch: that the cache does not break the cart, that your code does not slow pages down and that background jobs run.

What must not be cached

A page cache serves saved HTML instead of running PHP. The catalog and product pages can be sped up that way, but personal pages cannot: one customer would see another's cart.

Do not cacheWhy
/cart/, /checkout/, /my-account/The content is different for every customer
Addresses with ?add-to-cart= and wc-ajax=They change the cart
/wp-json/wc/store/The block cart's data
Requests with the cookies woocommerce_items_in_cart, woocommerce_cart_hash, wp_woocommerce_session_...The visitor has a cart

Popular cache plugins know these rules themselves. If the cache is set up on the server or in a CDN, the exclusions are added by hand.

Your code and speed

Four habits that keep a plugin from slowing the shop:

HabitExample
Limit querieslimit => 12 instead of -1
Take IDs when objects are not neededreturn => ids
Make no external requests while rendering a pageMove them to Action Scheduler
Remember heavy resultsA transient for an hour

Remembering a result

A transient is a value saved in the database for a while. Let us take the featured products list out of every request:

// wp-content/plugins/acme-shop/includes/products.php
function acme_featured_ids(): array
{
    $ids = get_transient('acme_featured_ids');
 
    if ($ids === false) {
        $ids = wc_get_products(['featured' => true, 'limit' => 8, 'return' => 'ids']);
 
        set_transient('acme_featured_ids', $ids, HOUR_IN_SECONDS);
    }
 
    return $ids;
}
 
add_action('woocommerce_update_product', function () {
    delete_transient('acme_featured_ids');
});

The first call runs the query and saves the result for an hour; the following ones take the ready array. The woocommerce_update_product hook drops the saved value when any product is changed — the list does not go stale. If the server has Redis or Memcached with an object cache plugin, transients are kept in memory.

The system scheduler

WordPress background jobs are triggered by site visits: no visitors means no emails and no exports. On a production server this is replaced with the system scheduler. Add define('DISABLE_WP_CRON', true); to wp-config.php and a run every minute to the server scheduler:

* * * * * cd /var/www/shop && wp cron event run --due-now --quiet

The command runs all due jobs, including the Action Scheduler queue.

Before launch

What to checkWhere
HTTPS on the whole siteThe site address in Settings → General starts with https
Shop pages are assignedWooCommerce → Settings → Advanced
A test order with a real paymentThe payment goes through and the bank's notification arrives
Emails are deliveredSending through SMTP, the email is not in spam
HPOS is onWooCommerce → Settings → Advanced → Features
No outdated templatesWooCommerce → Status, the Templates section
No failed jobsWooCommerce → Status → Scheduled Actions
Debugging is offWP_DEBUG is false in wp-config.php
BackupsScheduled, and a restore has been tested

The WooCommerce → Status page gathers most of this list: versions, settings, warnings in red.

Updates

WooCommerce is updated often. First update a copy of the shop on a test server, walk the path from the catalog to payment and only then update the production site. After an update run wp wc update from the console to update the database tables.

Common mistake

A full page cache is turned on for the production site for speed, and the cart is not checked as a second visitor. The first customer adds a product, the cart page gets into the cache, and everyone else sees someone else's cart or an empty one instead of their own. After setting up the cache open the shop in two different browsers and make sure the carts are independent.

Thanks for reading!

Donate to the site — we work hard for you.