Disclosure: We may receive compensation from the companies whose products we review if you click through our affiliate links.

How to Minify HTML in WordPress Without a Plugin

What is HTML Minification?

When you minify HTML it removes the unnecessary characters and lines in the source code. Indentation, comments, empty lines, etc. are not required in HTML. They just make the file easier to read. Cutting out all this unnecessary stuff can shave down your file size considerably. When you minify HTML code on your website, the server will send a much smaller page to the client making your website load quicker.

WordPress creates pages on demand by executing PHP code to put together the HTML version of your site and querying your database to get the content to insert into that HTML. There is no physical file that we can download and minify ourselves, so we will need to use a bit of PHP code inside the functions.php file of your theme. This code will compress the output HTML before being sent to your visitors. Below are two screenshots that show a webpage before and after HTML Minification.

Before HTML Minification

Before HTML Minify

After HTML Minification

After HTML Minify

When doing our homework on speeding up the site we also looked at our web hosting. We found both Kinsta and Rocket.net (see our Rocket.net vs Kinsta comparison) to be extremely fast if you’re up for the additional cost of managed hosting. Before that our shared hosting was from HostGator (cloud hosting) which was quick, just not manage-hosting level of quick.

Step 1: Create a Child Theme

Before we edit the functions.php file, it’s always best to create a child theme. Using a child theme will allow you to revert back to the parent theme if there are problems. Also, any changes you make will not be deleted if your parent theme gets updated.

If you prefer not to create a child theme or you do not feel comfortable doing this on your own, there is a great lightweight plugin you can use called Code Snippets. Code Snippets is an easy, clean and simple way to add code snippets to your site. It removes the need to add custom snippets to your theme’s functions.php file.

Step 2: Edit your Child Theme functions.php File

There are 2 different ways we can edit the functions.php file in your child theme.

Inside WordPress Control Panel

While you are logged into WordPress you can access and edit the functions.php file of your theme by going to Appearance > Editor and selecting Theme Functions on the right hand side of the page.

Edit the File Directly in cPanel

Log into your cPanel File Manager. Go to the public_html/wp-content/themes/ and choose the folder of your current theme or child theme if you have created one. The functions.php file will be inside your theme folder.

Copy and paste the code below inside your functions.php file and save.

class FLHM_HTML_Compression
{
protected $flhm_compress_css = true;
protected $flhm_compress_js = true;
protected $flhm_info_comment = true;
protected $flhm_remove_comments = true;
protected $html;
public function __construct($html)
{
if (!empty($html))
{
$this->flhm_parseHTML($html);
}
}
public function __toString()
{
return $this->html;
}
protected function flhm_bottomComment($raw, $compressed)
{
$raw = strlen($raw);
$compressed = strlen($compressed);
$savings = ($raw-$compressed) / $raw * 100;
$savings = round($savings, 2);
return '<!--HTML compressed, size saved '.$savings.'%. From '.$raw.' bytes, now '.$compressed.' bytes-->';
}
protected function flhm_minifyHTML($html)
{
$pattern = '/<(?<script>script).*?<\/script\s*>|<(?<style>style).*?<\/style\s*>|<!(?<comment>--).*?-->|<(?<tag>[\/\w.:-]*)(?:".*?"|\'.*?\'|[^\'">]+)*>|(?<text>((<[^!\/\w.:-])?[^<]*)+)|/si';
preg_match_all($pattern, $html, $matches, PREG_SET_ORDER);
$overriding = false;
$raw_tag = false;
$html = '';
foreach ($matches as $token)
{
$tag = (isset($token['tag'])) ? strtolower($token['tag']) : null;
$content = $token[0];
if (is_null($tag))
{
if ( !empty($token['script']) )
{
$strip = $this->flhm_compress_js;
}
else if ( !empty($token['style']) )
{
$strip = $this->flhm_compress_css;
}
else if ($content == '<!--wp-html-compression no compression-->')
{
$overriding = !$overriding; 
continue;
}
else if ($this->flhm_remove_comments)
{
if (!$overriding && $raw_tag != 'textarea')
{
$content = preg_replace('/<!--(?!\s*(?:\[if [^\]]+]|<!|>))(?:(?!-->).)*-->/s', '', $content);
}
}
}
else
{
if ($tag == 'pre' || $tag == 'textarea')
{
$raw_tag = $tag;
}
else if ($tag == '/pre' || $tag == '/textarea')
{
$raw_tag = false;
}
else
{
if ($raw_tag || $overriding)
{
$strip = false;
}
else
{
$strip = true; 
$content = preg_replace('/(\s+)(\w++(?<!\baction|\balt|\bcontent|\bsrc)="")/', '$1', $content); 
$content = str_replace(' />', '/>', $content);
}
}
} 
if ($strip)
{
$content = $this->flhm_removeWhiteSpace($content);
}
$html .= $content;
} 
return $html;
} 
public function flhm_parseHTML($html)
{
$this->html = $this->flhm_minifyHTML($html);
if ($this->flhm_info_comment)
{
$this->html .= "\n" . $this->flhm_bottomComment($html, $this->html);
}
}
protected function flhm_removeWhiteSpace($str)
{
$str = str_replace("\t", ' ', $str);
$str = str_replace("\n",  '', $str);
$str = str_replace("\r",  '', $str);
$str = str_replace("// The customizer requires postMessage and CORS (if the site is cross domain).",'',$str);
while (stristr($str, '  '))
{
$str = str_replace('  ', ' ', $str);
}   
return $str;
}
}
function flhm_wp_html_compression_finish($html)
{
return new FLHM_HTML_Compression($html);
}
function flhm_wp_html_compression_start()
{
ob_start('flhm_wp_html_compression_finish');
}
add_action('get_header', 'flhm_wp_html_compression_start');

Step 3: Make Sure Everything is Working

After you have added the code, you can check to see if the HTML is being minified on Google Chrome by right clicking the page and selecting “View page source.” If everything is working correctly, it should look like the example picture I gave at the top of this page.

I highly recommend you check all aspects of your website after you add this code. Check and make sure all plugins and theme functionality is working properly.

If you enjoyed this tutorial, please be sure to follow us on Facebook and Twitter. You can also find us on Freelancer if you need some help with your WordPress website or web development issues.

David Green

My name is David and I am the founder and author of Zuziko. I love WordPress and have built sites, themes and plugins. I am passionate about web development and have created Zuziko as a way to share my knowledge and experience with the world. My WordPress user profile.

13 thoughts on “How to Minify HTML in WordPress Without a Plugin”

  1. wee

    Thank you for sharing. How can I get the JS compression to be false for certain pages. I’ve tried a few attempts at this, but have been unsuccessful. What would your recommendation be?

  2. wee

    I would also like to add; add_action(‘template_redirect’, ‘flhm_wp_html_compression_start’); this seems to be working fine too. Which one is better to use.
    Thanks.

  3. wee

    Hello,
    First of all, thank you very much for your sharing.
    add_action(‘init’, ‘flhm_wp_html_compression_start’); it caused me a problem and I continued with “get_header” as you wrote. Seems fine for now.
    What I’m wondering is, does the code block in this article cause any security vulnerabilities? It just popped into my mind. I would be very happy if you answer. ,As far as I understand, the code cleans more spaces, right?
    Respects.

  4. this code is not work 🙁

  5. Martin

    After some more time I run into further issues with my early fix. Here is the updated fix.

    Replace:

    function flhm_wp_html_compression_start()
    {
    ob_start(‘flhm_wp_html_compression_finish’);
    }
    add_action(‘get_header’, ‘flhm_wp_html_compression_start’);

    With:

    function flhm_wp_html_compression_start()
    {
    // don’t minify HTML on this domain or part of the domain
    $blacklist_domain = ‘.localdev’;

    // if the function is called on a blacklisted domain, don’t minify HTML
    if (false !== strpos(site_url(), $blacklist_domain) || is_user_logged_in()) {
    return;
    }

    ob_start(‘flhm_wp_html_compression_finish’);
    }
    add_action(‘init’, ‘flhm_wp_html_compression_start’, 1);

  6. Martin

    Unfortunately, the above code breaks for me the current version of WordPress.

    Using add_action(‘init’, ‘flhm_wp_html_compression_start’); instead of add_action(‘get_header’, ‘flhm_wp_html_compression_start’); breaks creating and updating Gutenberg posts for me. It happens even when you prevent the code from running in the admin dashboard.

    if (!is_admin()) {
    add_action(‘init’, ‘flhm_wp_html_compression_start’);
    }

    Disabling CSS, JS and comments compression also didn’t help.

    Here is the fix that works for me. I also included a code that prevents HTML compression on a specified by you domain, for example the local environment.

    Replace:

    function flhm_wp_html_compression_start()
    {
    ob_start(‘flhm_wp_html_compression_finish’);
    }
    add_action(‘get_header’, ‘flhm_wp_html_compression_start’);

    With:

    function flhm_wp_html_compression_start()
    {
    // don’t minify HTML on this domain or part of the domain
    $blacklist_domain = ‘.localdev’;

    // if the function is called on a blacklisted domain, don’t minify HTML
    if (false !== strpos(site_url(), $blacklist_domain)) {
    return;
    }

    ob_start(‘flhm_wp_html_compression_finish’);
    }
    add_action(‘template_redirect’, ‘flhm_wp_html_compression_start’);

  7. Diego

    Change add_action(‘get_header’, ‘flhm_wp_html_compression_start’); to add_action(‘init’, ‘flhm_wp_html_compression_start’);

  8. Charles Smith

    I usually build in Laravel and avoid WordPress when possible. I decided to build my marketing site in WordPress and find the out-of-the-box messy source code horrible at best.

    I didn’t want to load a plugin for this, so when I found your code to be so simple to implement, I was super excited.

    Simply Brilliant!!!

  9. Prathiban Sukumaran

    Hi, your code worked great. I was using Autoptimize but now I do not need that plugin, thank you. But there is one issue, my product carousel has stopped working. Could you tell me how to fix this issue?

    Thanks in advance!

  10. Roger

    I used the code but essential JS and CSS stopped working. I was looking for HTML minify and it did work. However, can it be edited to just simply minify HTML? Do I set the values to false if I don’t want JS or CSS minified?

    • David Green

      Hi Roger,

      Yes, that is correct! If you don’t want to compress JS and CSS just set those values to false like shown below.

      protected $flhm_compress_css = false;
      protected $flhm_compress_js = false;
      
  11. Ant

    Awesome! I’m always looking for ways to do things without installing a million plugins. Works great on my website.

    Thank you!

Leave a Comment

Share via
Copy link
Powered by Social Snap