Skip to content

Instantly share code, notes, and snippets.

@Viper007Bond
Last active October 29, 2023 14:23
Show Gist options
  • Save Viper007Bond/5192117 to your computer and use it in GitHub Desktop.
Save Viper007Bond/5192117 to your computer and use it in GitHub Desktop.
WordPress: Times how long it takes each filter and action to run and displays results at the end of the page. Quick and dirty.
<?php
/**
* This little class records how long it takes each WordPress action or filter
* to execute which gives a good indicator of what hooks are being slow.
* You can then debug those hooks to see what hooked functions are causing problems.
*
* This class does NOT time the core WordPress code that is being run between hooks.
* You could use similar code to this that doesn't have an end processor to do that.
*
* @version 0.4
* @author Alex Mills (Viper007Bond)
*
* This code is released under the same license as WordPress:
* http://wordpress.org/about/license/
*/
// Here's a test to make sure it's working
add_action( 'wp_footer', function() { sleep( 2 ); } );
class WhatIsSoSlow {
public $data = array();
function __construct() {
add_action( 'all', array( $this, 'filter_start' ) );
add_action( 'shutdown', array( $this, 'results' ) );
}
// This runs first for all actions and filters.
// It starts a timer for this hook.
public function filter_start() {
$current_filter = current_filter();
$this->data[ $current_filter ][]['start'] = microtime( true );
add_filter( $current_filter, array( $this, 'filter_end' ), 99999 );
}
// This runs last (hopefully) for each hook and records the end time.
// This has problems if a hook fires inside of itself since it assumes
// the last entry in the data key for this hook is the matching pair.
public function filter_end( $filter_data ) {
$current_filter = current_filter();
remove_filter( $current_filter, array( $this, 'filter_end' ), 99999 );
end( $this->data[ $current_filter ] );
$last_key = key( $this->data[ $current_filter ] );
$this->data[ $current_filter ][ $last_key ]['stop'] = microtime( true );
return $filter_data;
}
// Processes the results and var_dump()'s them. TODO: Debug bar panel?
public function results() {
$results = array();
foreach ( $this->data as $filter => $calls ) {
foreach ( $calls as $call ) {
// Skip filters with no end point (i.e. the hook this function is hooked into)
if ( ! isset( $call['stop'] ) )
continue;
if ( ! isset( $results[ $filter ] ) )
$results[ $filter ] = 0;
$results[ $filter ] = $results[ $filter ] + ( $call['stop'] - $call['start'] );
}
}
asort( $results, SORT_NUMERIC );
$results = array_reverse( $results );
var_dump( $results );
}
}
new WhatIsSoSlow();
@harpreetslater
Copy link

harpreetslater commented Oct 1, 2020

First of all, thanks for sharing this script. Secondly, I want to know if this script works with every WordPress theme? Currently, I own a website about renting cars and I want to add this script to it. I have used WordPress car rental service theme and I want to know if this script is compatible with the best WordPress theme. I called it the best because I love how it works and how it looks. I strongly suggest it to everyone that wants to have a theme for their car dealership or renting service.

@PoeHaH
Copy link

PoeHaH commented Jun 28, 2022

this gives an error:

 Fatal error: Uncaught Error: Too few arguments to function ghosttown\WhatIsSoSlow::filter_end(), 0 passed in /var/www/vhosts/buyterpenesonline.com/wp-includes/class-wp-hook.php on line 287 and exactly 1 expected

Change line 44 to:

public function filter_end( $filter_data = null) {

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment