Title: Compatilbity with caching plugins
Last modified: August 24, 2016

---

# Compatilbity with caching plugins

 *  Resolved [GatorDog](https://wordpress.org/support/users/gatordog/)
 * (@gatordog)
 * [11 years, 1 month ago](https://wordpress.org/support/topic/compatilbity-with-caching-plugins/)
 * We’ve had a request to add compatibility with your plugin to the GatorCache plugin.
   I took a look at your code and it probably would be incompatible with any caching
   plugin or any other plugin that performs output buffering. The issue is here:
 *     ```
       add_action('template_redirect', 'jch_buffer_start', 0);
       add_action('shutdown', 'jch_buffer_end', 0);
       ```
   
 * You’re manually shutting down the buffering when you don’t really have to. Additionally,
   you can’t be really sure what buffer you’re ending in the jch_buffer_end function
   if there are other output buffers present. The following minor adjustment would
   work better, accomplish the same thing and be more compatible with other plugins
   that also do output buffering:
 *     ```
       add_action('template_redirect', 'jch_buffer_start', 0);
       // remove this line
       // add_action('shutdown', 'jch_buffer_end', 0);
       // add the buffer end function as a callback to ob_start
       function jch_buffer_start()
       {
               ob_start('jch_buffer_end');
       }
       // modify this so it uses the passed buffer contents
       function jch_buffer_end($sHtml)
       {
               // remove this section, it is no longer needed
               /*$sHtml = '';
   
               while(ob_get_level())
               {
                       $sHtml = ob_get_clean() . $sHtml;
               }*/
   
               if (JchOptimizeHelper::validateHtml($sHtml))
               {
                       return jchoptimize($sHtml);
               }
               /*else
               {*/
                       return $sHtml;
               //}
       }
       ```
   
 * As mentioned this would make your plugin compatible with caching plugins, since
   you hook your buffer after they do.
 * [https://wordpress.org/plugins/jch-optimize/](https://wordpress.org/plugins/jch-optimize/)

Viewing 11 replies - 1 through 11 (of 11 total)

 *  Plugin Author [codealfa](https://wordpress.org/support/users/codealfa/)
 * (@codealfa)
 * [11 years, 1 month ago](https://wordpress.org/support/topic/compatilbity-with-caching-plugins/#post-6137343)
 * Thanks for your feedback. When you say ‘compatible’ I’m assuming you mean having
   the JCH optimize plugin run before the caching plugin so the output of JCH optimize
   is cached by the plugin.
 * Coming from a Joomla! background, one of the challenges I have with WordPress
   is that there is no native way of accessing the processed HTML. Therefore, developers
   who need to access some or all parts of the HTML have to resort to PHP’s buffering
   functions to do so. I’ve found that different developers are doing all sorts 
   of things so compatibility between plugins that uses output buffering is a major
   challenge.
 * The problem with your solution, which I’ve tried before, is that the plugin needs
   the complete HTML that is enclosed between (and including) the <html> tags in
   order to work. When the optimize function is called in the buffer callback, there’s
   no guarantee what is in the current buffer. If throughout the page requests the
   buffers are not properly nested, which I have encountered, the function gets 
   called before the full HTML is ready. I’ve even seen different parts of the HTML
   in different levels of buffer, which is why I’m looping through all the levels.
 * I’m shutting down the buffer just before WordPress does it anyhow. I do it in
   the shutdown hook using a priority of ‘0’ and WordPress calls this function in
   the shutdown hook using a ‘1’ priority in the wp-includes/functions.php file:
 *     ```
       function wp_ob_end_flush_all() {
       	$levels = ob_get_level();
       	for ($i=0; $i<$levels; $i++)
       		ob_end_flush();
       }
       ```
   
 * In the absence of a native buffer API and a way for users to order which plugins
   should run first, I think as developers we should work together on a convention
   that makes our plugins work well together. I would propose my solution with two
   small changes. I could hook into shutdown a little earlier but restarting the
   buffer after running my functions so caching plugins can hook into shutdown after
   and cache the optimized HTML. So my codes would look like this:
 *     ```
       add_action('template_redirect', 'jch_buffer_start', 0);
        add_action('shutdown', 'jch_buffer_end', -1);
       ```
   
 *  and
 *     ```
       function jch_buffer_end()
       {
               $sHtml = '';
   
               while (ob_get_level())
               {
                       $sHtml = ob_get_clean() . $sHtml;
               }
   
               ob_start();
   
               if (JchOptimizeHelper::validateHtml($sHtml))
               {
                       echo jchoptimize($sHtml);
               }
               else
               {
                       echo $sHtml;
               }
       }
       ```
   
 *  Plugin Author [codealfa](https://wordpress.org/support/users/codealfa/)
 * (@codealfa)
 * [11 years, 1 month ago](https://wordpress.org/support/topic/compatilbity-with-caching-plugins/#post-6137344)
 * I should also add that I am aware of the ‘incompatibility’ with caching plugins.
   I generally test the plugin with WP Super Cache so I regrettably noted that with
   the last change the caching plugin no longer cached the optimized HTML, something
   I would prefer to have happen myself. The ‘consolation’ though was that JCH Optimize
   comes with its own level of caching.
 * I’ve put in a lot of effort to have the plugin run as fast as possible. The results
   of the combining and minification functions are cached so on subsequent requests
   the plugin should run under 100ms.
 * Anyway I’ll continue to research to see if there’s a way I can have my plugin
   compatible with other plugins including caching plugins.
 *  Thread Starter [GatorDog](https://wordpress.org/support/users/gatordog/)
 * (@gatordog)
 * [11 years, 1 month ago](https://wordpress.org/support/topic/compatilbity-with-caching-plugins/#post-6137346)
 * Hmmmm, I’m not really sure you understand how PHP output buffering works. Regarding
   your statement, “having the JCH optimize plugin run before the caching plugin
   so the output of JCH optimize is cached by the plugin” — is the exact opposite
   of how PHP buffering functions. In the context of WordPress or even a simple 
   php script, if you want your output to be cached by another buffer, you’d start
   your buffer after the preceding cache buffer. Your buffering callback would change
   the output which in turn is fed to the preceeding buffer, the cache – so in effect
   your “optimized” page would be used for the cache or main buffer.
 *  Plugin Author [codealfa](https://wordpress.org/support/users/codealfa/)
 * (@codealfa)
 * [11 years, 1 month ago](https://wordpress.org/support/topic/compatilbity-with-caching-plugins/#post-6137349)
 * Yes I’m quite aware of that actually. When I say ‘having the JCH Optimize plugin
   run’, I’m referring to the jchoptimize function that gets called when the buffer
   closes. That’s where the optimization happens. So generally yes that would mean
   starting the caching buffer before the JCH Optimize buffer as you have rightly
   pointed out.
 * With the current implementation though, assuming the caching occurs whenever 
   your buffer closes, then the caching will occur before the optimize function 
   runs even if you started your buffer first since I’m looping through and closing
   all the levels of buffering and concatenating them. There’s no harm done here
   as I explained earlier since WordPress does the exact same thing one step later
   anyway so me doing it shouldn’t affect anybody in anyway that WordPress hasn’t.
 * I’m trying to ensure that the full HTML is available whenever I call the optimize
   function. Your solution doesn’t work for me as I’ve seen plugins starting buffers
   they’re not closing, and I’ve seen plugins closing buffers that haven’t started.
   I’ve also seen different parts of the HTML in different levels so I can’t rely
   on a callback to ensure I’m getting the HTML when my buffer closes.
 *  Plugin Author [codealfa](https://wordpress.org/support/users/codealfa/)
 * (@codealfa)
 * [11 years, 1 month ago](https://wordpress.org/support/topic/compatilbity-with-caching-plugins/#post-6137365)
 * What I actually meant was to have the optimize process run before the caching
   process. Thought you would have understood that since one plugin can be hooking
   into various functions running at different times so you wouldn’t necessarily
   have one plugin running in its entirety before another in WordPress.
 *  Thread Starter [GatorDog](https://wordpress.org/support/users/gatordog/)
 * (@gatordog)
 * [11 years, 1 month ago](https://wordpress.org/support/topic/compatilbity-with-caching-plugins/#post-6137407)
 * Using the callback I described, your optimizer will get the full site html generated
   by WordPress, that’s what will be returned when the output buffering ends on 
   it’s own and your callback is ran. Then if there is a cache buffer after yours,
   your html is fed to their callback and saved to a cache – it may do some other
   things, add debug info etc, but this is on top of your optimized page.
 * Consider the following code:
 *     ```
       ob_start('my_cache_function');
       ob_start('my_optimizing_function');
       echo '<pre>Hello World</pre>';
       function my_optimizing_function($html);
           return $html . "\n" . '<!-- Optimized by great optimizer -->';
       }
       function my_cache_function($html){
          return $html . "\n" . '<!-- Cached by mighty cacher -->';
       }
       ```
   
 * This will simply return:
 *     ```
       <pre><Hello World></pre>
       <!-- Optimized by great optimizer -->
       <!-- Cached by mighty cacher -->
       ```
   
 *  Plugin Author [codealfa](https://wordpress.org/support/users/codealfa/)
 * (@codealfa)
 * [11 years, 1 month ago](https://wordpress.org/support/topic/compatilbity-with-caching-plugins/#post-6137431)
 * I don’t think you understand what I am trying to explain so maybe I need to work
   on how to explain myself clearer. While the callback works beautifully in a simple
   script where you are in control of all the codes, that’s not the case in WordPress
   where users can add may different plugins that are handling output buffering 
   in many different ways.
 * The callback is not an option for me as I simply cannot release an update that
   will knowingly break the functionality of the plugin on some sites. I hope you
   can understand that.
 * I want the plugin to be compatible with caching as much as you do so I may have
   a solution that works for both of us. I’ve tested it with GatorCache and it works.
   I’ve edited the jch_buffer_end function as such:
 *     ```
       function jch_buffer_end()
       {
               $sHtml = '';
               $bFlag = FALSE;
   
               while (ob_get_level())
               {
                       $sHtml = ob_get_clean() . $sHtml;
   
                       ob_start();
   
                       if (JchOptimizeHelper::validateHtml($sHtml))
                       {
                               $bFlag = TRUE;
   
                               break;
                       }
               }
   
               if ($bFlag)
               {
                       echo jchoptimize($sHtml);
               }
               else
               {
                       echo $sHtml;
               }
       }
       ```
   
 * If you can confirm that this works then this will be included in the next release.
 *  Plugin Author [codealfa](https://wordpress.org/support/users/codealfa/)
 * (@codealfa)
 * [11 years, 1 month ago](https://wordpress.org/support/topic/compatilbity-with-caching-plugins/#post-6137448)
 * I just thought I’d give one use case scenario that I’ve encountered where the
   callback implementation does not work for me. Remember I need the full HTML in
   order for the plugin to work:
 *     ```
       ob_start('my_optimizing_function');
   
       echo '<html>';
       echo '<head></head>';
       echo '<body>';
       echo '<pre>Hello World</pre>';
   
       ob_end_flush();
   
       echo '<pre>Hello again world</pre>';
       echo '</body>';
       echo '</html>';
   
       function my_optimizing_function($html)
       {
               $buffer = '<!--Optimization start-->' . "\n";
               $buffer .= $html . "\n";
               $buffer .= '<!--Optimization ends-->' . "\n";
   
               return $buffer;
       }
       ```
   
 * Will return:
 *     ```
       <!--Optimization start-->
       <html><head></head><body><pre>Hello World</pre>
       <!--Optimization ends-->
       <pre>Hello again world</pre></body></html>
       ```
   
 * With my solution:
 *     ```
       ob_start();
   
       echo '<html>';
       echo '<head></head>';
       echo '<body>';
       echo '<pre>Hello World</pre>';
   
       ob_end_flush();
   
       echo '<pre>Hello again world</pre>';
       echo '</body>';
       echo '</html>';
   
       $sHtml = '';
   
       while (ob_get_level())
       {
               $sHtml = ob_get_clean() . $sHtml;
   
               ob_start();
   
               if($sHtml)
               {
                       break;
               }
       }
   
       echo my_optimizing_function($sHtml);
   
       function my_optimizing_function($html)
       {
               $buffer = '<!--Optimization start-->' . "\n";
               $buffer .= $html . "\n";
               $buffer .= '<!--Optimization ends-->' . "\n";
   
               return $buffer;
       }
       ```
   
 * returns:
 *     ```
       <!--Optimization start-->
       <html><head></head><body><pre>Hello World</pre><pre>Hello again world</pre></body></html>
       <!--Optimization ends-->
       ```
   
 * And there are others.
 * My solution is also compatible with your plugin:
 *     ```
       ob_start('my_cache_function');
       ob_start();//Optimization buffer starts
   
       echo '<pre>Hello World</pre>';
   
       $sHtml = '';
   
       while (ob_get_level())
       {
               $sHtml = ob_get_clean() . $sHtml;
   
               ob_start();
   
               if($sHtml)
               {
                       break;
               }
       }
   
       echo my_optimizing_function($sHtml);
   
       function my_optimizing_function($html)
       {
               return $html . "\n" . '<!-- Optimized by great optimizer -->';
       }
   
       function my_cache_function($html)
       {
               return $html . "\n" . '<!-- Cached by mighty cacher -->';
       }
       ```
   
 * returns:
 *     ```
       <pre>Hello World</pre>
       <!-- Optimized by great optimizer -->
       <!-- Cached by mighty cacher -->
       ```
   
 * Of course, if you need the full HTML for your plugin to work correctly too then
   your plugin will fail in the first scenario.
 *  Plugin Author [codealfa](https://wordpress.org/support/users/codealfa/)
 * (@codealfa)
 * [11 years ago](https://wordpress.org/support/topic/compatilbity-with-caching-plugins/#post-6137487)
 * Update released with compatibility with caching plugins.
 *  Thread Starter [GatorDog](https://wordpress.org/support/users/gatordog/)
 * (@gatordog)
 * [11 years ago](https://wordpress.org/support/topic/compatilbity-with-caching-plugins/#post-6137507)
 * This may work in some cases where other plugins don’t use output buffering. Not
   sure why you wouldn’t want to do this correctly and use a callback from ob_start.
   This is what every other successful WordPress plugin does to modify the output–
   including AutoOptimize, WPMinify, WordPress Https, NExtgen, the list goes on…
 *  Plugin Author [codealfa](https://wordpress.org/support/users/codealfa/)
 * (@codealfa)
 * [11 years ago](https://wordpress.org/support/topic/compatilbity-with-caching-plugins/#post-6137510)
 * I don’t know why you have completely ignored and disregarded what I have said
   about encountering cases where the callback doesn’t work as expected. This works
   well if the buffers are properly nested. The PHP Manual also points this out.
 * [http://php.net/ob_start/](http://php.net/ob_start/)
    _“Output buffers are stackable,
   that is, you may call ob\_start() while another ob\_start() is active. Just make
   sure that you call ob\_end\_flush() the appropriate number of times.”_
 * In WordPress you can’t guarantee that this will be the case when users can install
   any number of arbitrary plugins that are doing all sorts of things with buffering.
   These plugins are hooking into all manner of different actions and have little
   control of the order in which hooked actions are called with respect to all the
   other plugins.
 * If using the callback works for the other plugins then that’s fine. You may consider
   what I’m doing to be unorthodox but for me “to do this correctly” means to do
   it in a way that works. I’ve tested it with GatorCache and other plugins using
   output buffering and it works in all scenarios when the callback fails in some.
 * Have you tested the latest version at all? As I have already stated I am also
   interested in having the plugin compatible with other plugins, not just GatorCache,
   so confirming whether this works or not for you would be more helpful than insisting
   I write codes in a particular way.

Viewing 11 replies - 1 through 11 (of 11 total)

The topic ‘Compatilbity with caching plugins’ is closed to new replies.

 * ![](https://ps.w.org/jch-optimize/assets/icon-128x128.png?rev=1135491)
 * [JCH Optimize](https://wordpress.org/plugins/jch-optimize/)
 * [Frequently Asked Questions](https://wordpress.org/plugins/jch-optimize/#faq)
 * [Support Threads](https://wordpress.org/support/plugin/jch-optimize/)
 * [Active Topics](https://wordpress.org/support/plugin/jch-optimize/active/)
 * [Unresolved Topics](https://wordpress.org/support/plugin/jch-optimize/unresolved/)
 * [Reviews](https://wordpress.org/support/plugin/jch-optimize/reviews/)

 * 11 replies
 * 2 participants
 * Last reply from: [codealfa](https://wordpress.org/support/users/codealfa/)
 * Last activity: [11 years ago](https://wordpress.org/support/topic/compatilbity-with-caching-plugins/#post-6137510)
 * Status: resolved