0

I am noticing that for various reasons I am using lots of string replacements in Wordpress and I am concerned about this impact on performance once it goes live.

I am not advanced in caching but it seems most Wordpress caching plugins seem to check a page in its entirety. If a page contains data that changes then it will be re-requesting the page from server and the string replaces will be happening again.

So for data that doesn't change the same replaces can be happening on every page load (I think?).

I found out that the transient API is automatically cached by memcache so I came up with this code to use for replacing strings.

It hashes the input values then stores them as a transient so the next time these exact values are requested it doesn't perform an operation from string, it just loads it from memory.

Here is code:

// values to replace.  Key is item to search for, Value is value to replace it with
// you can have as many as you like
$itemsToReplace = array(
    'current-menu-parent' => 'current-menu-parent active',
    'item' => 'name'
);

// the input string (this would be the value passed to the wordpress filter)
// I just made small string here to show what I mean
$inputString = '<div class="current-menu-parent">some menu item</div>';

// replace or get cached value
$output = Cstr_replace($itemsToReplace, $inputString);


function Cstr_replace(array $items, $input)
{
    // create key by combining hashes
    // have to use crc32 for one as transient name is only 45 long
    $hashKey = hash('crc32',(string)$items).':'.hash('md5',(string)$input);

    // check if the hash exists.
    // if it exists then it means these exact values have already been replaced and we can use cached
    $filtered = get_transient( $hashKey );
    if ( false === $filtered ) {
        // It wasn't there, so replace string and save to transient
        $filtered = str_replace(array_flip($items),$items, $input);
        set_transient( $hashKey, $filtered, 12 * HOUR_IN_SECONDS );
    }

    // return either cached or newly generated string
    return (string)$filtered;
}

I am wondering though if this is a good practice. Will it aid performance? Is there a better way to achieve this? This could put a lot of entries in there. Is that bad? Also there is a small chance of collisions I think but maths is not my strong suit.

I use something similar in a C# application and it greatly increases its performance but it is standalone code without all the addons and such of wordpress so I don't know if this is pointless in this context.

Is this good to use or should I do something different?

  • What counts as "lots of string replacements"? How much are you doing this? – s_ha_dum Jun 9 '15 at 18:34
  • It varies. I would imagine maximum would not be more than 100. Typical 10-30. – Guerrilla Jun 9 '15 at 19:24
0

You would probably get at least equally good performance by simply adding the classes with a filter, and it is certainly neater and closer to the way the WordPress is meant to be modified:

function add_classes_wpse_190966($classes) {
  if (in_array('current-menu-parent',$classes)) {
    $classes[] = 'active';
  }
  return $classes;
}
add_filter('nav_menu_css_class','add_classes_wpse_190966');

Or, with an array of values:

function add_classes_wpse_190966($classes) {
  $itemsToReplace = array(
    'current-menu-parent' => 'current-menu-parent active',
    'item' => 'name'
  );
  $classes = array_intersect_key(array_combine($classes,$classes),$itemsToReplace);

  foreach ($classes as $v) {
    $classes[] = $itemsToReplace[$v];
  }

  return $classes;
}
add_filter('nav_menu_css_class','add_classes_wpse_190966');
|improve this answer|||||
  • I am not sure what you mean. That works when there is a class filter available but the issue I have is when I must modify the html as there is no filter available to me for the specific need I have as the majority of plugins I have this issue with typically just have a filter at the end of a large code block. Obviously using a native function or a function override would be faster as there would then not be any large string manipulations but what if that is not possible? I am trying to work out how to improve the performance of string replace on raw html by using cache for those instances. – Guerrilla Jun 9 '15 at 19:19
  • So what are your conditions to trigger the class addition? You seem to be trying to use existing classes? – s_ha_dum Jun 9 '15 at 19:53
  • Lets say for instance removing swear words from everywhere on a website and replacing them with a different word. – Guerrilla Jun 9 '15 at 19:57
  • How does the code above indicate that project? – s_ha_dum Jun 9 '15 at 20:05
  • The code replaces string and saves it in transient with a hashkey so next time string replace doesnt happen, it uses the transient by checking the hash. It would apply to any string replace regardless of context. – Guerrilla Jun 9 '15 at 20:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.