Making WordPress faster (with and without plugins)

There’s a few small, but unnecessarily things that can slow our WordPress page loads. They’re easily fixed with either a code snippet or a light-weight plugin.

I’ve started storing snippets with WPCodeBox as a convenient and light-weight option, but of course, you don’t need to do the same.


Unused styles from the Block Editor

My last video on disabling Gutenberg focused mainly on removing the 130kb of unused Gutenberg (inline and external) styles and SVGs.  It did not cover common situations such as using a 3rd party page builder for pages and the block editor for posts.

The Disable Gutenberg plugin I previously mentioned allows you to conditionally disable Gutenberg by pages, posts, CPT and individual IDs. But its disabling of styles is global.  It’s all or nothing with the styles there.

Those with good coding skills will be able  to use the code below and make it apply where needed.

// Remove Gutenberg CSS.
add_action( 'wp_enqueue_scripts', function() {
wp_dequeue_style( 'wp-block-library' ); // External CSS
wp_dequeue_style( 'wp-block-library-theme' ); // Inline CSS
wp_dequeue_style( 'global-styles' ); // Inline CSS

}, 20 );

// Remove blank SVGs 
remove_action( 'wp_body_open', 'wp_global_styles_render_svg_filters' );


Those with WPCodeBox can use it’s condition builder to adapt it to your set up more easily. Below has the styles removed from everywhere except posts.



WPCodeBox –  25% off coupon

Just enter “beaverjunction” to get the best discount available. WPCodeBox .


Disable emoji/twemoji support

Emoji support was added to WordPress 2015.  Few sites needed it and today most devices support emojis natively. If you see an emoji above it is due to native support.

Removing emoji support is a small saving. Presently around 40kb (uncompressed) of JavaScript, but it also runs a regex (regular expression) on each page which can have an impact on some devices.

I have recently swapped my snippet to this one by SmartWP.   If you know of an even better snippet please consider submitting it to WPCodeBin which is a brand new initiative from WPCodeBox .

//Disable emojis in WordPress
add_action( 'init', 'smartwp_disable_emojis' );

function smartwp_disable_emojis() {
remove_action( 'wp_head', 'print_emoji_detection_script', 7 );
remove_action( 'admin_print_scripts', 'print_emoji_detection_script' );
remove_action( 'wp_print_styles', 'print_emoji_styles' );
remove_filter( 'the_content_feed', 'wp_staticize_emoji' );
remove_action( 'admin_print_styles', 'print_emoji_styles' );
remove_filter( 'comment_text_rss', 'wp_staticize_emoji' );
remove_filter( 'wp_mail', 'wp_staticize_emoji_for_email' );
add_filter( 'tiny_mce_plugins', 'disable_emojis_tinymce' );

function disable_emojis_tinymce( $plugins ) {
if ( is_array( $plugins ) ) {
return array_diff( $plugins, array( 'wpemoji' ) );
} else {
return array();

A highly rated free plugin alternative is Disable EmojisWP Hive’s automatic test shows that activation of this plugin deceases memory slightly.

Remove JQuery migrate

JQuery migrate is not intended as a permanent fixture of WordPress, but I don’t believe there is plan for its removal.

It is supposed to help developers to “migrate” to newer versions of jQuery.  But essentially it is acting as backward compatibility fix for out of date themes and plugins. Assuming your software providers stay up-to-date it is redundant.

It’s a JavaScript file that is presently only 25kb (uncompressed), but it is loaded in the header (along with jQuery) and so is often flagged as render blocking resource by Google’s Lighthouse/PageSpeed Insights.

The snippet I use comes from Jeff Starr (Creator of Disable Gutenberg and author of many WP books and plugins). This removes JQuery migrate from the frontend only.

function remove_jquery_migrate( $scripts ) {

if ( ! is_admin() && isset( $scripts->registered['jquery'] ) ) {

$script = $scripts->registered['jquery'];

if ( $script->deps ) { 
$script->deps = array_diff( $script->deps, array( 'jquery-migrate' ) );
add_action( 'wp_default_scripts', 'remove_jquery_migrate' );


A free plugin alternative is Remove jQuery Migrate.  Again, WPHive shows us a memory gain with activating this plugin.

What about JQuery itself ?

It’s a 86 kb (288kb uncompressed) render blocking resource that can often serves no or little purpose. For example, on the frontend of this blog it is only needed to make the mobile menu drop down. There is a strong case presented on Make.WP which claims:

  • jQuery is the most common JavaScript-based performance problem in themes.
  • jQuery usage in themes correlates with worse LCP performance.
  • Removing jQuery may lead to 80% less JavaScript load.

I think it’s fair to say the need for  jQuery is increasingly questioned in the WordPress community It’s also been absent from the official WordPress themes over recent years.

But for many of us it is not going to be a simple matter of adding a snippet like below and hoping for the best.

add_action( 'wp_enqueue_scripts', function() {
wp_dequeue_script( 'jquery');
wp_deregister_script( 'jquery');

}, 20 );

jQuery has been such a huge part of WordPress for so long that many plugins and themes have (for the sake of code efficiency at the time) built on this library.

For example, I use Beaver Builder where both the page builder editor and individual frontend modules depend on it to work. Being pragmatic, it maybe much easier to use a caching (or performance) plugin to defer or delay its load.

That said, in a follow-up I will share my (probably foolhardy) journey into trying to create a jQuery free Beaver Builder starter site using WPCodeBox (here is that post).

Final Mentions

I noticed WP outputs imageloaded.js ( “images done yet or what?”). I considered this at 5.6 kb uncompressed to be more of a help than a hinderance.

Although this is a security thing, attacks on a site will impact performance so it is worth considering  XML-RPC and the need for frontend use of WP REST API. In addition to Jeff Starr’s REST API plugin there is this code snippet from Scott Hartley:

/* Disable REST API link in HTTP headers */
remove_action('template_redirect', 'rest_output_link_header', PHP_INT_MAX);

/* Disable REST API links in HTML */
remove_action('wp_head', 'rest_output_link_wp_head', PHP_INT_MAX);
remove_action('xmlrpc_rsd_apis', 'rest_output_rsd');

/* Disable REST API */
if (version_compare(get_bloginfo('version'), '4.7', '>=')) {

add_filter('rest_authentication_errors', 'disable_wp_rest_api'); 
} else { 

function disable_wp_rest_api($access) { 
if (!is_user_logged_in()) { 
$message = apply_filters('disable_wp_rest_api_error', __('REST API restricted to logged in users.', 'disable-wp-rest-api'));

return new WP_Error('rest_login_required', $message, array('status' => rest_authorization_required_code())); 
return $access; 

function disable_wp_rest_api_legacy() {

// REST API 1.x
add_filter('json_enabled', '__return_false');
add_filter('json_jsonp_enabled', '__return_false');

// REST API 2.x
add_filter('rest_enabled', '__return_false');
add_filter('rest_jsonp_enabled', '__return_false'); 

This disables for non-logged in users.

Leave a Comment