WordPress.org

Make WordPress Core

Opened 4 years ago

Last modified 6 months ago

#43258 new enhancement

Output buffering

Reported by: nextendweb Owned by:
Milestone: Awaiting Review Priority: normal
Severity: normal Version:
Component: General Keywords: 2nd-opinion
Focuses: docs Cc:

Description

I see that more and more theme and plugin developers start to use output buffering functions for the whole site as they need to manipulate the site's content. For example:

  • Cache the page
  • Combine JS and CSS files
  • Lad JS and CSS files for widgets only when needed
  • Place SEO related things

As it is not officially available in WordPress, developers need to find their way to buffer the output. Probably the most common action is the 'template_redirect', where they can place ob_start()

Then they have to close their output buffer, probably the best action to do that is 'shutdown'.

It wouldn't be a problem, if this method only used once on your site. When multiple plugin or theme use this technique, they should close only their output buffers. As output buffers are LIFO stacked, it is very important to close in the order they were added.

For example:

Cache plugin:

<?php
add_action('template_redirect', function(){
   ob_start();
});

add_action('shutdown', function(){
  $html = ob_get_clean();
  //Let's cache the html and show it...
});

CSS minify plugin:

<?php
add_action('template_redirect', function(){
   ob_start();
});

add_action('shutdown', function(){
  $html = ob_get_clean();
  //Let's find CSS files, minify them and replace the originals
});

In this case the page will be cached and the CSS files will be minified afterwards which will slow down the site as they should be in reverse order. We can fix that with priority, but both 'template_redirect' and 'shutdown' should get the same priority to make sure we close the related output buffer.

Documentation
What I propose is to have an official documentation which suggests the right way to use output buffering. It would help prevent several conflicts between plugins and themes.

Future
It would be great to see in WordPress core an in-built output buffering system. Then the developers wouldn't need to start and close output buffers on their own. WordPress would do the output buffering and at the end it would allow the filtering of the content.

<?php
echo apply_filters('wp_output', $output);

Attachments (1)

class-wp-output-buffer.php (1.2 KB) - added by nextendweb 6 months ago.
WP_Output_Buffer class

Download all attachments as: .zip

Change History (8)

#1 follow-up: @swissspidy
4 years ago

  • Focuses coding-standards removed

It would be great to see in WordPress core an in-built output buffering system. Then the developers wouldn't need to start and close output buffers on their own. WordPress would do the output buffering and at the end it would allow the filtering of the content.

That sounds a lot like treating the symptoms not the cause.

#2 in reply to: ↑ 1 @nextendweb
4 years ago

Replying to swissspidy:

That sounds a lot like treating the symptoms not the cause.

And what do you think, what is the cause?

#3 @DrewAPicture
4 years ago

  • Keywords 2nd-opinion added

What I propose is to have an official documentation which suggests the right way to use output buffering. It would help prevent several conflicts between plugins and themes.

If we were pursue some kind of "official" mechanism for output buffering, probably the best place for that documentation to live would be in the Theme Developer Handbook here: https://developer.wordpress.org/themes/

#4 @nextendweb
4 years ago

I started to investigate how different plugins and themes use output buffering to modify the output of the page. Here you can check the collection: https://github.com/nextend/wp-ob-plugins-themes/blob/master/README.md

It would be great to hear feedback from other developers to find the preferred usage of output buffering and then create and official documentation on this topic.

@nextendweb
6 months ago

WP_Output_Buffer class

#5 @nextendweb
6 months ago

I propose the attached WP_Output_Buffer class, which would be an optional feature what developers could enable and use when needed. It simply starts an output buffer and runs the 'output_buffer' filter on the content of the buffer which holds the whole output of the site.

Also the class gives suggested priorities for different use cases so developers can hook to the right point.

<?php
<?php
if (class_exists('WP_Output_Buffer')) {
    WP_Output_Buffer::enable();

    add_filter('output_buffer', array(
        $this,
        'prepareOutput'
    ), WP_Output_Buffer::DEFAULT_PRIORITIES['CONTENT']);
} else {
    /**
     * The plugin and theme mechanism for old WordPress version which do not support this feature.
     */
}

Several huge plugins use global output buffers like:

  • Wordfence Security @mmaunder
  • Jetpack
  • Really Simple SSL @rogierlankhorst
  • SG Optimizer @hristo-sg
  • LiteSpeed Cache @litespeedtech
  • WP Fastest Cache @emrevona
  • Autoptimize @optimizingmatters
  • Smush @alexdunae
  • W3 Total Cache @joemoto
  • WP Rocket
  • EWWW Image Optimizer @nosilver4u
  • Smart Slider 3

and much more: wpdirectory.net => ob_start\( ?array and wpdirectory.net => ob_start\(('|")

#6 @OptimizingMatters
6 months ago

Agreed: some standardization around the use of the OB could certainly be helpful.

#7 @DaanvandenBergh
6 months ago

Absolutely!

However, if using an output buffer isn't the recommended method (which is what @swissspidy seems to be suggesting) I'd love to see some documentation on what the preferred way is to manipulate a HTML document in its entirety.

Note: See TracTickets for help on using tickets.