WordPress - Minify CSS, HTML, JS files using PHP
Tags: wordpress, php, html, javascript
Published: 2021-11-09 09:55:46

As web developers or designers, we all have an enemy which is called Site Speed. There are so many ways to speed up your web page, we are going to discuss one of those ways. Minifying HTML, CSS & JavaScript.

Minifying means removing redundant or unnecessary data such as spacing, well-named variables, and comments.

The minified version of the code [HTML, CSS, JavaScript] is 48% smaller in general. In some cases, minification can reduce the file size by as much as 60%. For example, there's a 176 kb difference between the original and minified version of the jQuery/JavaScript library.

It reduces web page load times and bandwidth usage on websites and improves website speed and accessibility.

So, we are going to minify WordPress using a simple PHP function. Add below codes to your functions.php, if you are using a child theme add inside child-theme/functions.php.

Step One Create a Class:
```
class WP_HTML_Compression{
 	protected $wp_compress_css = true;
 	protected $wp_compress_js = true;
 	protected $wp_info_comment = true;
 	protected $wp_remove_comments = true;
 	protected $html;
 	public function __construct($html)
 	{
 		if (!empty($html)) {
 			$this->wp_parseHTML($html);
 		}
 	}
 	public function __toString()
 	{
 		return $this->html;
 	}
 	protected function wp_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 wp_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->wp_compress_js;
 				} else if (!empty($token['style'])) {
 					$strip = $this->wp_compress_css;
 				} else if ($content == '<!--wp-html-compression no compression-->') {
 					$overriding = !$overriding;
 					continue;
 				} else if ($this->wp_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->wp_removeWhiteSpace($content);
 			}
 			$html .= $content;
 		}
 		return $html;
 	}
 	public function wp_parseHTML($html)
 	{
 		$this->html = $this->wp_minifyHTML($html);
 		if ($this->wp_info_comment) {
 			$this->html .= "\n" . $this->wp_bottomComment($html, $this->html);
 		}
 	}
 	protected function wp_removeWhiteSpace($str)
 	{
 		$str = str_replace("\t", ' ', $str);
 		$str = str_replace("\n",  '', $str);
 		$str = str_replace("\r",  '', $str);
 		$str = str_replace(" This function requires postMessage and CORS (if the site is cross domain).", '', $str);
 		while (stristr($str, '  ')) {
 			$str = str_replace('  ', ' ', $str);
 		}
 		return $str;
 	}
 }
```
Step Two call the functions:
```
function wp_html_compression_finish($html)
 {
 	return new WP_HTML_Compression($html);
 }
 function wp_wp_html_compression_start()
 {
 	ob_start('wp_html_compression_finish');
 }
```
Final step call Wp hook:
```
add_action('get_header', 'wp_wp_html_compression_start');
```

All to getherL
```
class WP_HTML_Compression{
 	protected $wp_compress_css = true;
 	protected $wp_compress_js = true;
 	protected $wp_info_comment = true;
 	protected $wp_remove_comments = true;
 	protected $html;
 	public function __construct($html)
 	{
 		if (!empty($html)) {
 			$this->wp_parseHTML($html);
 		}
 	}
 	public function __toString()
 	{
 		return $this->html;
 	}
 	protected function wp_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 wp_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->wp_compress_js;
 				} else if (!empty($token['style'])) {
 					$strip = $this->wp_compress_css;
 				} else if ($content == '<!--wp-html-compression no compression-->') {
 					$overriding = !$overriding;
 					continue;
 				} else if ($this->wp_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->wp_removeWhiteSpace($content);
 			}
 			$html .= $content;
 		}
 		return $html;
 	}
 	public function wp_parseHTML($html)
 	{
 		$this->html = $this->wp_minifyHTML($html);
 		if ($this->wp_info_comment) {
 			$this->html .= "\n" . $this->wp_bottomComment($html, $this->html);
 		}
 	}
 	protected function wp_removeWhiteSpace($str)
 	{
 		$str = str_replace("\t", ' ', $str);
 		$str = str_replace("\n",  '', $str);
 		$str = str_replace("\r",  '', $str);
 		$str = str_replace(" This function requires postMessage and CORS (if the site is cross domain).", '', $str);
 		while (stristr($str, '  ')) {
 			$str = str_replace('  ', ' ', $str);
 		}
 		return $str;
 	}
 }
 function wp_html_compression_finish($html)
 {
 	return new WP_HTML_Compression($html);
 }
 function wp_wp_html_compression_start()
 {
 	ob_start('wp_html_compression_finish');
 }
 add_action('get_header', 'wp_wp_html_compression_start');
```
Conclusion:
Instead of using plugins to minify simply add this function to your WordPress site and see the magic🏃‍♂️.