How to Improve WordPress Performance

Performance
  1. Speed Up WP_Query
  2. Use no_found_rows in WP_Query
  3. Disable WordPress CSS Files
  4. Where Will This Disable the Loading?
  5. How Can I Disable Loading on a Specific Page?
  6. How can I disable on a custom post types single pages?
  7. Monitor Queries with Query Monitor
  8. Cache Policy
  9. Apache Servers
  10. Nginx
  11. Consider Your Front-End Assets

WordPress performance can be a difficult task to approach but with these simple tips and quick wins you can be off to a great start. In this article we will discuss various ways for you to improve the performance of your WordPress site without using any plugins.

Speed Up WP_Query

As developers, we often need to get posts and other content from the WordPress database. We don’t need to write raw SQL queries because the WP_Query API and its methods provide us with a safe and efficient way to retrieve data from the database. We just need an array of arguments, and the WP_Query object will build the actual SQL query.

Considering query performance may not bring huge advantages for smaller websites but if you want to be ready for growth you should optimize your queries. A few simple tweaks you can speed up your website considerably.

Use no_found_rows in WP_Query

By default, adding the posts_per_page parameter causes WordPress to perform an additional SQL query for the number of rows found for the query which can significantly negative impact performance of that query. We can disable this functionality by adding the no_found_rows parameter and setting it to true.

When we don’t need pagination, we should always set no_found_rows to true, as shown below.

<?php

$args  = array(
	'post_type'      => 'posts',
	'posts_per_page' => 12,
	'no_found_rows'  => true,
);
$query = new WP_Query( $args );

Disable WordPress CSS Files

The WordPress CSS files, such as block-styles.css is loaded on every page that is created with the Gutenberg editor, however most of your landing pages would be using a custom PHP/HTML template with little to no blocks used!

Although a small win in terms of performance, it's little things like this that build up to become a major increase in performance. 

You can disable the loading of WordPress CSS blocks files by using the following snippet in your functions file

add_action( 'wp_enqueue_scripts', function () {
    if ( is_front_page()
            || is_home()
            || is_archive()
    ) {
        wp_dequeue_style( 'global-styles' );
        wp_dequeue_style( 'wp-block-library' );
        wp_dequeue_style( 'wp-block-library-theme' );
    }
}, 100 );

Where Will This Disable the Loading?

The code snippet above will prevent loading on the following:

  • Homepage/Front-Page
  • Archive Pages - the blog posts archive for example

How Can I Disable Loading on a Specific Page?

You can add to the list of places to disable by simply adding to the if statement, like so

add_action( 'wp_enqueue_scripts', function () {
    if ( is_front_page()
            || is_home()
            || is_archive()
            || get_the_ID() === 12 // New page added here: if the page or post ID is 12, the styles won't be loaded.
    ) {
        wp_dequeue_style( 'global-styles' );
        wp_dequeue_style( 'wp-block-library' );
        wp_dequeue_style( 'wp-block-library-theme' );
    }
}, 100 );

How can I disable on a custom post types single pages?

You can disable on a post type basis by adding the following to the if statement

add_action( 'wp_enqueue_scripts', function () {
    if ( is_front_page()
            || is_home()
            || is_archive()
            || is_singular( [ 'services' ] ) // now the files won't be loaded for the `services` post type.
    ) {
        wp_dequeue_style( 'global-styles' );
        wp_dequeue_style( 'wp-block-library' );
        wp_dequeue_style( 'wp-block-library-theme' );
    }
}, 100 );

Monitor Queries with Query Monitor

With the use of the Query Monitor plugin on local development you can monitor which parts of your theme or plugins are performing too many queries and address those issue. In my experience, heavy use of Advanced Custom Fields has led to far too many queries being executed for page load, even as high as 90 queries for a single page! 

If you do find one plugin or template file making far too many requests, you can consider replacing the plugin or refactoring the WP_Query that is taking too long to get a result.

I would only recommend this plugin for local development as it really provides no benefit to running it on production servers. 

Cache Policy

An efficient cache policy helps improve page load times on repeat visits by storing these files locally in the user's browser. Every time a browser loads a page, it must download all your page resources such as HTML, CSS, JavaScript, and images.

When caching is enabled, a user's first visit to your page won't be any quicker; however, subsequent visits to the page will be, due to the cached content.

Apache Servers

This snippet goes into .htaccess 

<IfModule mod_expires.c>
  ExpiresActive On

 # Images
  ExpiresByType image/jpeg "access plus 1 year"
  ExpiresByType image/gif "access plus 1 year"
  ExpiresByType image/png "access plus 1 year"
  ExpiresByType image/webp "access plus 1 year"
  ExpiresByType image/svg+xml "access plus 1 year"
  ExpiresByType image/x-icon "access plus 1 year"

  # Video
  ExpiresByType video/webm "access plus 1 year"
  ExpiresByType video/mp4 "access plus 1 year"
  ExpiresByType video/mpeg "access plus 1 year"

  # Fonts
  ExpiresByType font/ttf "access plus 1 year"
  ExpiresByType font/otf "access plus 1 year"
  ExpiresByType font/woff "access plus 1 year"
  ExpiresByType font/woff2 "access plus 1 year"
  ExpiresByType application/font-woff "access plus 1 year"

  # CSS, JavaScript
  ExpiresByType text/css "access plus 1 year"
  ExpiresByType text/javascript "access plus 1 year"
  ExpiresByType application/javascript "access plus 1 year"

  # Others
  ExpiresByType application/pdf "access plus 1 year"
  ExpiresByType image/vnd.microsoft.icon "access plus 1 year"
</IfModule>

Nginx

This snippet goes into the Nginx configuration file, inside the server block.

location ~* \.(jpg|jpeg|gif|png|webp|css|js|woff|woff2|otf|ttf|svg|pdf|mp4|mpeg)$ {
    expires 365d;
}

Consider Your Front-End Assets

The size and quantity of assets loaded onto the front-end of your WordPress site can have a massive impact on the load time of your pages. Most plugins will load one, if not multiple stylesheets and JavaScript files so you should pay close attention to which plugins are loading which files and think if you really need them on certain pages.

A major example of plugins loading unnecessary front-end assets is Contact Form 7. The plugin loads all of it's assets regardless of whether there is a form on the page or not. Caching plugins like SwiftPerformance have a setting to disable the entire Contact Form 7 plugin when there is no contact form on the page so I highly recommend you take the time to have a good look through your caching plugin and see if there is an option to disable the plugins you think don't need to be loaded on some pages. It goes without saying that you should have a testing strategy in place to make sure that the plugin is still working as intended after disabling it's functionality on a certain section of your website.

Another thing you can do is consider the frameworks you are using to produce the front-end of your website, for example Bootstrap or jQuery. Alternatives such as Tailwind CSS for your front-end will allow you to reduce your production CSS file size down by a massive amount and is super easy to get setup. If you're still using jQuery for your front-end JavaScript functionality then I recommend you switch to a modern framework such as Vue.js or if your theme is pretty simple in terms of user functionality, then just stick with vanilla JavaScript. Removing the use of jQuery from your theme will allow you to remove that call to the server for the JavaScript file.

Copyright © 2024 | bonnick.dev