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
After HTML Minification
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);
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.
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);
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’);
Change add_action(‘get_header’, ‘flhm_wp_html_compression_start’); to add_action(‘init’, ‘flhm_wp_html_compression_start’);
You should at least provide your source: https://blog.finderonly.net/wp-content/uploads/2011/05/minifier-script.txt
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!!!
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!
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?
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.
Awesome! I’m always looking for ways to do things without installing a million plugins. Works great on my website.
Thank you!