Problem/Motivation

I've been profiling a site for performance recently. And wysiwyg_filter_parse_valid_elements() keeps coming up as a badly offending function. In the case of this site, there are multiple textfields on my content type that all use the same WYSIWYG filter. The list of $valid_elements never changes. Rather than calling this fairly expensive function for each of them, utilize the drupal_static pattern.

Proposed resolution

Utilize the drupal_static pattern.

Remaining tasks

User interface changes

n/a

API changes

n/a

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

heddn’s picture

The performance difference on a node that has 6 text fields.
Without patch: Times called: 6 | Total Self Cost: 3.39 | Total Inclusive Cost: 4.08
With patch: Times called: 6 | Total Self Cost: 0.63 | Total Inclusive Cost: 0.76

This means that each call to wysiwyg_filter_parse_valid_elements() takes approximately 0.60ms. If you have a lot of text fields or are loading a lot of data with node_load_multiple() or are using Views on a large number of nodes, this will take 0.60ms for each of those fields.

A further example:
10 nodes in a view with 5 fields each = 30ms
vs.
approximately 1ms with the patch.

joelpittet’s picture

Status: Needs review » Reviewed & tested by the community
Issue tags: +Performance

This is great! I had one view that was reporting 1.3secons and this patch brought that down to 2ms!

Thanks @heddn

Here's a git diff -w . view of that patch because it looks bigger than it is.

diff --git a/sites/all/modules/contrib/wysiwyg_filter/wysiwyg_filter.inc b/sites/all/modules/contrib/wysiwyg_filter/wysiwyg_filter.inc
index c76308b..8614093 100644
--- a/sites/all/modules/contrib/wysiwyg_filter/wysiwyg_filter.inc
+++ b/sites/all/modules/contrib/wysiwyg_filter/wysiwyg_filter.inc
@@ -123,6 +123,9 @@ function wysiwyg_filter_get_elements_blacklist() {
  * @see wysiwyg_filter_process()
  */
 function wysiwyg_filter_parse_valid_elements($valid_elements) {
+  $parsed_elements = &drupal_static(serialize($valid_elements));
+
+  if (!isset($parsed_elements)) {
     // Remove whitespaces and split valid elements from a comma separate list of items into an array.
     $valid_elements = array_map('drupal_strtolower', array_filter(explode(',', preg_replace('#\s+#', '', $valid_elements))));
     $parsed_elements = array();
@@ -260,6 +263,7 @@ function wysiwyg_filter_parse_valid_elements($valid_elements) {

     // Sort HTML elements alphabetically (for filter tips).
     ksort($parsed_elements);
+  }

   return $parsed_elements;
 }

@heddn it may be worth writing that with a an early return to make the diff smaller and less indenting?

aka:

$parsed_elements = &drupal_static(serialize($valid_elements));
if (isset($parsed_elements)) {
  return $parsed_elements;
}

Let you or the maintainer decided which is preferred

brockfanning’s picture

I lean towards smaller patches myself, so just putting up joelpittet's suggestion in case the maintainer feels the same. But credit for this issue should go to heddn and joelpittet for seeing/fixing/testing the problem. Thanks guys!

  • axel.rutz committed 8fabab1 on 7.x-1.x authored by heddn
    Issue #2361839 by heddn, brockfanning, joelpittet: Profiling...

geek-merlin’s picture

Status: Reviewed & tested by the community » Fixed

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.