如何缩小php页面html输出?
Posted
技术标签:
【中文标题】如何缩小php页面html输出?【英文标题】:How to minify php page html output? 【发布时间】:2011-09-07 16:41:38 【问题描述】:我正在寻找可以像谷歌页面速度一样缩小我的 php 页面 html 输出的 php 脚本或类。
我该怎么做?
【问题讨论】:
基于@RakeshS 的单线答案:ob_start(function($b)return preg_replace(['/\>[^\S ]+/s','/[^\S ]+\</s','/(\s)+/s'],['>','<','\\1'],$b););
@FranciscoPresencia 这是一件非常糟糕的事情。您正在破坏脚本标签、前置标签等。
这是真的,正如他在回答 cmets 中指出的那样,它不适用于 <pre>
或 <code>
标签,因为它们需要空格来实现正确的结构。但是,<script>
通常应该是外部的,或者是内联的,但要严格使用;
,所以它也可以工作。哪些其他标签可能会破坏@Brad?我想不出别人。不过,我应该在我之前的评论之前添加 快速而肮脏的方式。
【参考方案1】:
CSS 和 javascript
考虑使用以下链接来缩小 Javascript/CSS 文件:https://github.com/mrclay/minify
HTML
告诉 Apache 使用 GZip 交付 HTML - 这通常会减少大约 70% 的响应大小。 (如果您使用 Apache,配置 gzip 的模块取决于您的版本:Apache 1.3 使用 mod_gzip,而 Apache 2.x 使用 mod_deflate。)
接受编码:gzip、deflate
内容编码:gzip
使用 following snippet 在 ob_start 的缓冲区的帮助下从 HTML 中删除空格:
<?php
function sanitize_output($buffer)
$search = array(
'/\>[^\S ]+/s', // strip whitespaces after tags, except space
'/[^\S ]+\</s', // strip whitespaces before tags, except space
'/(\s)+/s', // shorten multiple whitespace sequences
'/<!--(.|\s)*?-->/' // Remove HTML comments
);
$replace = array(
'>',
'<',
'\\1',
''
);
$buffer = preg_replace($search, $replace, $buffer);
return $buffer;
ob_start("sanitize_output");
?>
【讨论】:
这是一个很好的功能,但是如果你使用 PRE 标签要小心它,有时换行会被删除。 这段代码应该在哪里,在脚本的顶部还是底部? 你也可以使用 Minify 库中的 Minify_HTML 类($content = \Minify_HTML::minify($content);
,你甚至可以为内联代码添加回调到 js/css 压缩器)。见github.com/mrclay/minify/blob/master/min/lib/Minify/HTML.php
这也破坏了内联 JavaScript(即在 <script>
标记中)在每个语句的末尾没有 ;
或有使用 //
的 cmets
这将从 textarea、pre、input、img 中删除空格,这也会破坏内联 javascript。如果有人不乐意使用基于正则表达式的 DOM 解析 this solution 的笨重类,效果很好【参考方案2】:
如果您想正确执行,请打开 gzip。你也可以这样做:
$this->output = preg_replace(
array(
'/ 2,/',
'/<!--.*?-->|\t|(?:\r?\n[ \t]*)+/s'
),
array(
' ',
''
),
$this->output
);
通过将您的 html 变成一行,没有制表符,没有新行,没有 cmets,这会删除大约 30% 的页面大小。里程可能会有所不同
【讨论】:
两者都做会进一步减少所需的字节数。 实际上两者都做与 gzip 相同,在 700kb 的页面上,gzip 会将其降低到大约 400kb,preg_replace() 大约 450kb(全部取决于内容)两者都将像 399kb gzip 删除相同的空格,然后压缩它 这可能有潜在危险,因为它还会删除 IE 条件... - 您需要将其更改为 // 不行,去掉太多,乱码。在 W3C 有效之前它不是有效的。 不幸的是,它还破坏了 Javascript 代码,例如生成更复杂的谷歌地图实现——这正是我需要这样的功能。【参考方案3】:我尝试了几个缩小器,它们要么删除的太少,要么删除的太多。
此代码删除了多余的空格和可选的 HTML(结束)标签。它也很安全,不会删除任何可能破坏 HTML、JS 或 CSS 的内容。
代码还显示了如何在 Zend Framework 中执行此操作:
class Application_Plugin_Minify extends Zend_Controller_Plugin_Abstract
public function dispatchLoopShutdown()
$response = $this->getResponse();
$body = $response->getBody(); //actually returns both HEAD and BODY
//remove redundant (white-space) characters
$replace = array(
//remove tabs before and after HTML tags
'/\>[^\S ]+/s' => '>',
'/[^\S ]+\</s' => '<',
//shorten multiple whitespace sequences; keep new-line characters because they matter in JS!!!
'/([\t ])+/s' => ' ',
//remove leading and trailing spaces
'/^([\t ])+/m' => '',
'/([\t ])+$/m' => '',
// remove JS line comments (simple only); do NOT remove lines containing URL (e.g. 'src="http://server.com/"')!!!
'~//[a-zA-Z0-9 ]+$~m' => '',
//remove empty lines (sequence of line-end and white-space characters)
'/[\r\n]+([\t ]?[\r\n]+)+/s' => "\n",
//remove empty lines (between HTML tags); cannot remove just any line-end characters because in inline JS they can matter!
'/\>[\r\n\t ]+\</s' => '><',
//remove "empty" lines containing only JS's block end character; join with next line (e.g. "\n\n</script>" --> "</script>"
'/[\r\n\t ]+/s' => '',
'/[\r\n\t ]+,[\r\n\t ]+/s' => ',',
//remove new-line after JS's function or condition start; join with next line
'/\)[\r\n\t ]?[\r\n\t ]+/s' => ')',
'/,[\r\n\t ]?[\r\n\t ]+/s' => ',',
//remove new-line after JS's line end (only most obvious and safe cases)
'/\),[\r\n\t ]+/s' => '),',
//remove quotes from HTML attributes that does not contain spaces; keep quotes around URLs!
'~([\r\n\t ])?([a-zA-Z0-9]+)="([a-zA-Z0-9_/\\-]+)"([\r\n\t ])?~s' => '$1$2=$3$4', //$1 and $4 insert first white-space character found before/after attribute
);
$body = preg_replace(array_keys($replace), array_values($replace), $body);
//remove optional ending tags (see http://www.w3.org/TR/html5/syntax.html#syntax-tag-omission )
$remove = array(
'</option>', '</li>', '</dt>', '</dd>', '</tr>', '</th>', '</td>'
);
$body = str_ireplace($remove, '', $body);
$response->setBody($body);
但请注意,当使用 gZip 压缩时,您的代码会被压缩得比任何压缩都多得多,因此将压缩和 gZip 结合使用是没有意义的,因为压缩所节省的时间会因压缩而丢失,并且还可以节省最少的时间。
这是我的结果(通过 3G 网络下载):
Original HTML: 150kB 180ms download
gZipped HTML: 24kB 40ms
minified HTML: 120kB 150ms download + 150ms minification
min+gzip HTML: 22kB 30ms download + 150ms minification
【讨论】:
是的,我同意这看似毫无意义,但它可以为您在 google 的 pagespeed 上获得一两个宝贵的分数,这与您的 google 排名有关。您的代码非常适合去除不需要的空间。谢谢:-) 这很好用, ="/" 有问题,所以我把 / 从 '~([\r\n\t ])?([a-zA-Z0-9]+ )="([a-zA-Z0-9_/\\-]+)"([\r\n\t ])?~s' => '$1$2=$3$4', //$1 和 $4 插入在属性之前/之后找到的第一个空白字符 好吧,碰巧我不想删除空格只是为了加快速度,而是因为 HTML 应该 应该这样,以免事情完全搞砸,就像内联块元素一样,但我也在寻找一种能够忽略需要在之前或之后有一个空格的东西(例如,文本块中的粗体元素)。 我发现某些 Jquery/Foundation 的东西有问题......除非我注释掉以下几行: //remove "empty" lines contains only JS's block end character;加入下一行(例如 "\n\n" --> "" // '/[\r\n\t ]+/s' => ' ', // '/[\r\n\t ]+,[\r\n\t ]+/s' => ',', 如果您使用服务器端缓存(对我来说 Smarty V3),min+gzip 是一个很好的解决方案,但在第一次调用时除外。因此,如果在第 15 次调用之后,服务器时间将会很有趣。 rule = 40x15 = (30x15 + 150) 但是对于第二次调用,访问者已经更快了。【参考方案4】:上述所有preg_replace()
解决方案都存在单行cmets、条件cmets 和其他陷阱的问题。我建议利用经过充分测试的Minify project,而不是从头开始创建自己的正则表达式。
在我的例子中,我将以下代码放在 PHP 页面的顶部以缩小它:
function sanitize_output($buffer)
require_once('min/lib/Minify/HTML.php');
require_once('min/lib/Minify/CSS.php');
require_once('min/lib/JSMin.php');
$buffer = Minify_HTML::minify($buffer, array(
'cssMinifier' => array('Minify_CSS', 'minify'),
'jsMinifier' => array('JSMin', 'minify')
));
return $buffer;
ob_start('sanitize_output');
【讨论】:
您的代码没有将 html 放在一行中 阅读Minify project FAQ 中的第一个问题。 TL;DR:忽略它们。 我试过了,还是不行。我的 php 文件中有 你把这段代码放在哪里?最后在页脚或页眉中? @francesco 这应该是您页面上的第一段代码。【参考方案5】:这对我有用。
function minify_html($html)
$search = array(
'/(\n|^)(\x20+|\t)/',
'/(\n|^)\/\/(.*?)(\n|$)/',
'/\n/',
'/\<\!--.*?-->/',
'/(\x20+|\t)/', # Delete multispace (Without \n)
'/\>\s+\</', # strip whitespaces between tags
'/(\"|\')\s+\>/', # strip whitespaces between quotation ("') and end tags
'/=\s+(\"|\')/'); # strip whitespaces between = "'
$replace = array(
"\n",
"\n",
" ",
"",
" ",
"><",
"$1>",
"=$1");
$html = preg_replace($search,$replace,$html);
return $html;
【讨论】:
这删除了接受答案未删除的空格。 ? 谢谢!【参考方案6】:在文档根目录之外创建一个 PHP 文件。如果您的文档根目录是
/var/www/html/
在其上一层创建一个名为 minify.php 的文件
/var/www/minify.php
复制粘贴下面的PHP代码到里面
<?php function minify_output($buffer) $search = array('/\>[^\S ]+/s','/[^\S ]+\</s','/(\s)+/s'); $replace = array('>','<','\\1'); if (preg_match("/\<html/i",$buffer) == 1 && preg_match("/\<\/html\>/i",$buffer) == 1) $buffer = preg_replace($search, $replace, $buffer); return $buffer; ob_start("minify_output");?>
保存 minify.php 文件并打开 php.ini 文件。如果是专用服务器/VPS 搜索以下选项,在使用自定义 php.ini 的共享主机上添加它。
auto_prepend_file = /var/www/minify.php
参考:http://websistent.com/how-to-use-php-to-minify-html-output/
【讨论】:
【参考方案7】:您可以查看这组类: https://code.google.com/p/minify/source/browse/?name=master#git%2Fmin%2Flib%2FMinify ,你会在那里找到 html/css/js 缩小类。
你也可以试试这个:http://code.google.com/p/htmlcompressor/
祝你好运:)
【讨论】:
【参考方案8】:您可以查看 HTML TIDY - http://uk.php.net/tidy
它可以作为 PHP 模块安装,并且会(正确、安全地)去除空格和所有其他脏东西,同时仍然输出完全有效的 HTML / XHTML 标记。它还会清理你的代码,这可能是一件好事,也可能是一件糟糕的事情,这取决于你在编写有效代码方面的能力;-)
此外,您可以在文件开头使用以下代码 gzip 输出:
ob_start('ob_gzhandler');
【讨论】:
问题是该站点将托管在共享上,我将无权安装此类模块。 很有可能,它已经被安装了。检查phpinfo()
... 至少应该安装zlib
允许您使用ob_gzhandler
。
我已经在使用if (substr_count($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip')) ob_start("ob_gzhandler"); else ob_start();
不是一样的吗?
是的,你真的不需要else ob_start()
部分,也不需要gzip 检查...ob_gzhandler
检测浏览器是否在内部支持任何压缩方法。只需拥有ob_start('ob_gzhandler');
就足够了。
由于额外的解析开销,TIDY 是否有可能比此处的其他答案慢?可能对开发有好处 - 然后您可以在实际源代码中纠正这些 HTML 错误 - 但我怀疑这是否是生产的最佳选择。【参考方案9】:
首先,gzip 可以帮助您的不仅仅是 Html Minifier
With nginx:
gzip on;
gzip_disable "msie6";
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
With apache you can use mod_gzip
第二:使用 gzip + Html Minification 可以大幅减小文件大小!!!
我创建了这个HtmlMinifier for PHP。
您可以通过composer检索它:composer require arjanschouten/htmlminifier dev-master
。
有一个 Laravel 服务提供者。如果你不使用 Laravel,你可以从 PHP 中使用它。
// create a minify context which will be used through the minification process
$context = new MinifyContext(new PlaceholderContainer());
// save the html contents in the context
$context->setContents('<html>My html...</html>');
$minify = new Minify();
// start the process and give the context with it as parameter
$context = $minify->run($context);
// $context now contains the minified version
$minifiedContents = $context->getContents();
如您所见,您可以在这里扩展很多东西,并且可以传递各种选项。 Check the readme 查看所有可用选项。
此HtmlMinifier 完整且安全。缩小过程需要 3 个步骤:
-
用占位符临时替换关键内容。
运行缩小策略。
恢复原始内容。
我建议您缓存视图的输出。缩小过程应该是一次性的过程。或者,例如基于间隔。
当时没有创建明确的基准。但是,缩小器可以根据您的标记将页面大小减小 5-25%!
如果您想添加自己的策略,可以使用 addPlaceholder
和 addMinifier
方法。
【讨论】:
感谢图书馆。说明没有说明我需要包含哪些 PHP 文件。我最终会弄明白的,但这是您应该在您的网站上添加的内容。 看起来它仍然需要 Illuminate\Support\Collection。它不是一个独立的 PHP 解决方案。 感谢您的反馈!这是一个composer 包。 I've updated the readme 使用以下规则:require __DIR__ . '/vendor/autoload.php';
您唯一要做的就是包含此文件。这是作曲家生成的!【参考方案10】:
我有一个 GitHub gist 包含用于缩小 HTML、CSS 和 JS 文件的 PHP 函数 → https://gist.github.com/taufik-nurrohman/d7b310dea3b33e4732c0
以下是如何使用输出缓冲区即时缩小 HTML 输出:
<?php
include 'path/to/php-html-css-js-minifier.php';
ob_start('minify_html');
?>
<!-- HTML code goes here ... -->
<?php echo ob_get_clean(); ?>
【讨论】:
【参考方案11】:如果要删除页面中的所有新行,请使用此快速代码:
ob_start(function($b)
if(strpos($b, "<html")!==false)
return str_replace(PHP_EOL,"",$b);
else return $b;
);
【讨论】:
【参考方案12】:感谢Andrew。 这是在 cakePHP 中使用它的方法:
-
下载minify-2.1.7
解压文件并将 min 子文件夹复制到 cake 的 Vendor 文件夹中
在 cake 的 View/Helper 中创建 MinifyCodeHelper.php,如下所示:
App::import('Vendor/min/lib/Minify/', 'HTML');
App::import('Vendor/min/lib/Minify/', 'CommentPreserver');
App::import('Vendor/min/lib/Minify/CSS/', 'Compressor');
App::import('Vendor/min/lib/Minify/', 'CSS');
App::import('Vendor/min/lib/', 'JSMin');
class MinifyCodeHelper extends Helper
public function afterRenderFile($file, $data)
if( Configure::read('debug') < 1 ) //works only e production mode
$data = Minify_HTML::minify($data, array(
'cssMinifier' => array('Minify_CSS', 'minify'),
'jsMinifier' => array('JSMin', 'minify')
));
return $data;
在 AppController 中启用我的 Helper
public $helpers = array('Html','...','MinifyCode');
5...瞧!
我的结论:如果 apache 的 deflate 和 headers 模块在您的服务器中被禁用,您的收益将减少 21% 的大小和 0.35 秒加上压缩请求(这个数字是在我的情况下)。
但是,如果您启用了 apache 的模块,则压缩响应没有显着差异(对我来说是 1.3%),并且压缩时间是相同的(对我来说是 0.3 秒)。
那么……我为什么要这样做? '因为我项目的文档都在 cmets(php、css 和 js)中,我的最终用户不需要看到这个;)
【讨论】:
【参考方案13】:您可以通过使用passthru
(exec
) 来调用像HTMLCompressor 这样经过良好测试的Java minifier。
记得使用2>&1
重定向控制台
但是,如果速度是一个问题,这可能没有用。我将它用于静态 php 输出
【讨论】:
【参考方案14】:最简单的方法是使用strtr 并删除空格。 话虽如此,请不要使用 javascript,因为它可能会破坏您的代码。
$html_minify = fn($html) => strtr($html, [PHP_EOL => '', "\t" => '', ' ' => '', '< ' => '<', '> ' => '>']);
echo $html_minify(<<<HTML
<li class="flex--item">
<a href="#"
class="-marketing-link js-gps-track js-products-menu"
aria-controls="products-popover"
data-controller="s-popover"
data-action="s-popover#toggle"
data-s-popover-placement="bottom"
data-s-popover-toggle-class="is-selected"
data-gps-track="top_nav.products.click(location:2, destination:1)"
data-ga="["top navigation","products menu click",null,null,null]">
Products
</a>
</li>
HTML);
// Response (echo): <li class="flex--item"><a href="#"class="-marketing-link js-gps-track js-products-menu"aria-controls="products-popover"data-controller="s-popover"data-action="s-popover#toggle"data-s-popover-placement="bottom"data-s-popover-toggle-class="is-selected"data-gps-track="top_nav.products.click(location:2, destination:1)"data-ga="["top navigation","products menu click",null,null,null]">Products</a></li>
【讨论】:
以上是关于如何缩小php页面html输出?的主要内容,如果未能解决你的问题,请参考以下文章
php 我创建的缩小php脚本,以最大限度地提高Googles页面速度得分