vlambda博客
学习文章列表

PHP对HTML进行代码压缩处理

压缩HTML的起因


如何提高网页加载速度,需要怎么对HTML页面优化相信是每个站长曾想到的问题,其实网页优化的方法还是很多。

如何压缩HTML,也就是说能不能把所有的HTML、JS、CSS在运行前都压缩成一行,清除注释标记、换行符、空格、制表符等。这样一个直接的好处是减小HTML页面体积来提高前端加载速度。很多人认为启动gzip,但一般启动gzip都比较少对HTML启动gzip压缩,因为现在的HTML都是动态的,不会使用浏览器缓存,而启用gzip的话每次请求都需要压缩,会比较消耗服务器资源,对JS、CSS启动gzip比较好是因为JS、CSS都会使用缓存。而大家也用了很多软件过滤一下压缩,也有在线js/css/html压缩工具,个人觉得也很麻烦,可读性很差。我认为如果将压缩功能做成一个函数的话,这样开发者看到的是未压缩的状态,但访客访问时,服务端的程序将HTML页面进行压缩,清除注释标记、换行符、空格、制表符等来达到减小了HTML体积的目的。

因此情留メ蚊子个人觉得压缩HTML的最大好处就是一本万利,只要写好了一次函数,以后在需要运用的时候调用一下就可以了,所有程序都可以使用,不会增加任何额外的开发工作。今天我就给大家分享一个我个人写的函数,请大家不妨试试看,相信大家会喜欢。

使用PHP压缩HTML注意事项


使用PHP来压缩HTML实现的方式主要是用正则表达式去查找,替换。在HTML压缩的时候,主要要注意下面几点:

  1. HTML文档中,多个空白字符等价为一个空白字符。也就是说换行等空白字符的删除是不安全的,有可能导致部分元素的样式产生差异。

  2. HTML中的pre、textarea标签里面的任何空白,都不能被删除,因此pre、textarea标签里面的内容格式需要保留,不能压缩。

  3. HTML中有可能有IE条件注释。这些条件注释是文档逻辑的一部分,不能被删除。因此去掉HTML注释的时候,有些注释是不能去掉的,比如:<!--[if lt IE9]> <![endif]-->

  4. 压缩嵌入式JS中的注释要注意,因为可能注释符号会出现在字符串中,比如:var url = "http://blog.cbylpt.cn"; // 前面的//不是注释

  5. 对于动态页面来说,HTML的压缩有可能还会增加服务器的CPU负担,得不偿失

  6. 特殊情况下可以使用<!--<nocompress>--><!--</nocompress>-->或者<nocompress></nocompress>来指定不压缩的代码

  7. pre、textarea标签不压缩

  8. 特别对JS的单行注释做出优化

/**
* 压缩HTML代码
*
* @author 情留メ蚊子 <[email protected]>
* @version 1.0.0.0 By 2016-11-23
* @link http://blog.cbylpt.cn
* @param string $html_source HTML源码
* @return string 压缩后的代码
*/
function qlwz_compress_html($html_source)
{
$chunks = preg_split('/(<!--<nocompress>-->.*?<!--<\/nocompress>-->|<nocompress>.*?<\/nocompress>|<pre.*?\/pre>|<textarea.*?\/textarea>|<script.*?\/script>)/msi', $html_source, -1, PREG_SPLIT_DELIM_CAPTURE);
$compress = '';
foreach ($chunks as $c) {
if (strtolower(substr($c, 0, 19)) == '<!--<nocompress>-->') {
$c = substr($c, 19, strlen($c) - 19 - 20);
$compress .= $c;
continue;
} elseif (strtolower(substr($c, 0, 12)) == '<nocompress>') {
$c = substr($c, 12, strlen($c) - 12 - 13);
$compress .= $c;
continue;
} elseif (strtolower(substr($c, 0, 4)) == '<pre' || strtolower(substr($c, 0, 9)) == '<textarea') {
$compress .= $c;
continue;
} elseif (strtolower(substr($c, 0, 7)) == '<script' && strpos($c, '//') != false && (strpos($c, "\r") !== false || strpos($c, "\n") !== false)) { // JS代码,包含“//”注释的,单行代码不处理
$tmps = preg_split('/(\r|\n)/ms', $c, -1, PREG_SPLIT_NO_EMPTY);
$c = '';
foreach ($tmps as $tmp) {
if (strpos($tmp, '//') !== false) { // 对含有“//”的行做处理
if (substr(trim($tmp), 0, 2) == '//') { // 开头是“//”的就是注释
continue;
}
$chars = preg_split('//', $tmp, -1, PREG_SPLIT_NO_EMPTY);
$is_quot = $is_apos = false;
foreach ($chars as $key => $char) {
if ($char == '"' && !$is_apos && $key > 0 && $chars[$key - 1] != '\\') {
$is_quot = !$is_quot;
} elseif ($char == '\'' && !$is_quot && $key > 0 && $chars[$key - 1] != '\\') {
$is_apos = !$is_apos;
} elseif ($char == '/' && $chars[$key + 1] == '/' && !$is_quot && !$is_apos) {
$tmp = substr($tmp, 0, $key); // 不是字符串内的就是注释
break;
}
}
}
$c .= $tmp;
}
}

$c = preg_replace('/[\\n\\r\\t]+/', ' ', $c); // 清除换行符,清除制表符
$c = preg_replace('/\\s{2,}/', ' ', $c); // 清除额外的空格
$c = preg_replace('/>\\s</', '> <', $c); // 清除标签间的空格
$c = preg_replace('/\\/\\*.*?\\*\\//i', '', $c); // 清除 CSS & JS 的注释
$c = preg_replace('/<!--[^!]*-->/', '', $c); // 清除 HTML 的注释
$compress .= $c;
}
return $compress;
}
压缩HTML总结


有些童鞋不推荐压缩HTML,主要原因除了上面所说的使用PHP压缩HTML注意事项外,通过gzip压缩已经能达到很好的效果。另外,因为产生影响HTML的角色太多(静态,动态,前端动态),也没什么量化指标,所以很难控制压缩成什么样(代码写成什么程度)。代码更需要考虑执行效率,而不是传输效率。对于动态页面来说,HTML的压缩有可能还会增加服务器的CPU负担,得不偿失。Google的压缩网页是因为早期他希望首页文本尽可能控制在一个或两个包内,而且他的首页太重要了,流量也很离谱。压缩一个字节,总流量一算都是个不小的数字,自然也就是必要之举了。进一步的压缩存在问题,除非能像Google一样充分测试(Google也仅压缩了少部分核心服务的页面),否则不推荐对HTML进行压缩处理。

但使用情留メ蚊子的PHP压缩HTML代码,能很好的解决这个问题。好了,还不快试试。