缩小 HTML/PHP

发布于 2024-09-06 11:30:10 字数 529 浏览 4 评论 0原文

我正在使用 gzip 来压缩 html/php 文件以及 js/css/等。这很好地减少了负载,但我也想“缩小”.html 和 .php 页面的标记。理想情况下,我想从 .htaccess 文件(我也进行 gzip 压缩)来控制它,而不是必须将 php 包含到每个文件中。

我希望输出类似于 http://google.comhttp://www.w3-edge.com/wordpress-plugins/w3-total-cache/ 和 http://css-tricks.com (均由 WordPress 的 W3 Total Cache 插件生成)。

任何人都可以推荐一个好方法来做到这一点。

I'm using gzip to compress my html/php files along with js/css/etc. This reduces the payload quite nicely but I also want to 'minify' my markup of both .html and .php pages. Ideally I'd like to control this from a .htaccess file (where I also do the gzipping) rather than the having to include php to each file.

I'd like the output to be like that of http://google.com or http://www.w3-edge.com/wordpress-plugins/w3-total-cache/ and http://css-tricks.com (both produced by W3 Total Cache plugin for WordPress).

Can anyone recommend a good way to do this.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

心病无药医 2024-09-13 11:30:10

查看示例,缩小 HTML 输出几乎没有任何作用。想一想:缩小对于 Javascript 来说非常有用,因为它使用许多重复的变量和函数名称,因为缩小所做的主要事情之一就是缩短它们以及对它们的所有引用。

另一方面,HTML 标记没有变量或函数的概念。页面的大部分权重来自实际的标记和内容。这不能被缩小。即使表单变量也需要单独保留,因为它们必须具有原始值才能由服务器正确处理。

Gzipping 已经可以非常有效地压缩空白。在 HTML 中,这确实是所能做的一切。

另外,缩小 PHP 也不适用,因为即使它有变量和函数,它也永远不会发送到客户端。对于在服务器上编译的内容来说,缩短名称不会带来性能优势。

如果您决定缩小 html,请查看执行此操作的 WordPress 插件的源代码。这就是开源的美妙之处。然而,我怀疑与 Gzipping 相比,收益可以忽略不计。

Looking at the examples, minifying the HTML output does almost nothing. Think about it: Minifying is great for Javascript which uses many repeating variable and function names, as one of the main things minifying does is shorten them and all references to them.

HTML markup, on the other hand, has no concept of variables or functions. Most of the weight of the page is from actual markup and content. This cannot be minified. Even form variables need to be left alone as they must have their original values to be processed correctly by the server.

Gzipping will already compress the whitespace very efficiently. In HTML, this is really all that can be done.

Also, minifying PHP doesn't apply, because even though it has variables and functions, it is never sent to the client. Shortening the names has no performance benefit for something compiled on the server.

If you are determined to minify your html, check out the source code for the WordPress plugin that does it. That's the beauty of open source. However, I suspect the gains will be negligible as compared to Gzipping.

会傲 2024-09-13 11:30:10

Peter Anselmo 将缩小与混淆混淆了。在代码混淆中,代码被缩小,变量被重命名为最短长度的任意名称。缩小只是减少代码大小的做法,例如删除空格,而不改变代码的值、名称或语法。

彼得·安塞尔莫(Peter Anselmo)也错误地认为,缩小加价只会带来微不足道的节省。例如,此页面显示节省了 18.31%,而且一开始就非常整洁。显然,他在发表观点之前从未检验过自己的观点。您可以使用 Pretty Diff 工具亲自查看成本节省情况,网址为 http://prettydiff.com/

您可以尝试反转Pretty Diff 使用工程师缩小引擎从 PHP 执行。该代码和随附文档可以在以下位置找到:prettydiff.com/markupmin.js

Peter Anselmo has confused minification for obfuscation. In code obfuscation the code is minified and variables are renamed to shortest length arbitrary names. Minification is merely the practice of reducing code size, such as white space removal, without altering the values, names, or syntax of code.

Peter Anselmo is also wrong that minifying markup results in an insignificant savings. This page, for instance, shows a savings of 18.31% and it was pretty tidy to begin with. Clearly, he has never tested his opinion before he put it out there. You can see the cost savings yourself using the Pretty Diff tool at http://prettydiff.com/

You can attempt to reverse engineer minification engine used by Pretty Diff to execute from PHP. That code and accompanied documentation can be found at: prettydiff.com/markupmin.js

血之狂魔 2024-09-13 11:30:10

我创建了 3 个可能需要优化的简单函数,但它们完成了自己的工作,它们是我用来格式化代码、日期、值等的更大类的一部分...:

使用它只需调用:

echo format::minify_html($html_output);

here是代码(仍处于测试阶段,但到目前为止还没有遇到很多问题)

<?php
class format(){
    static function minify_css($text){
        $from   = array(
        //                  '%(#|;|(//)).*%',               // comments:  # or //
            '%/\*(?:(?!\*/).)*\*/%s',       // comments:  /*...*/
            '/\s{2,}/',                     // extra spaces
            "/\s*([;{}])[\r\n\t\s]/",       // new lines
            '/\\s*;\\s*/',                  // white space (ws) between ;
            '/\\s*{\\s*/',                  // remove ws around {
            '/;?\\s*}\\s*/',                // remove ws around } and last semicolon in declaration block
            //                  '/:first-l(etter|ine)\\{/',     // prevent triggering IE6 bug: http://www.crankygeek.com/ie6pebug/
        //                  '/((?:padding|margin|border|outline):\\d+(?:px|em)?) # 1 = prop : 1st numeric value\\s+/x',     // Use newline after 1st numeric value (to limit line lengths).
        //                  '/([^=])#([a-f\\d])\\2([a-f\\d])\\3([a-f\\d])\\4([\\s;\\}])/i',
        );
        $to     = array(
        //                  '',
            '',
            ' ',
            '$1',
            ';',
            '{',
            '}',
            //                  ':first-l$1 {',
        //                  "$1\n",
        //                  '$1#$2$3$4$5',
        );
        $text   = preg_replace($from,$to,$text);
        return $text;
    }
    static function minify_js($text){
        $file_cache     = strtolower(md5($text));
        $folder         = TMPPATH.'tmp_files'.DIRECTORY_SEPARATOR.substr($file_cache,0,2).DIRECTORY_SEPARATOR;
        if(!is_dir($folder))            @mkdir($folder, 0766, true);
        if(!is_dir($folder)){
            echo 'Impossible to create the cache folder:'.$folder;
            return 1;
        }
        $file_cache     = $folder.$file_cache.'_content.js';
        if(!file_exists($file_cache)){
            if(strlen($text)<=100){
                $contents = $text;
            } else {
                $contents = '';
                $post_text = http_build_query(array(
                                'js_code' => $text,
                                'output_info' => 'compiled_code',//($returnErrors ? 'errors' : 'compiled_code'),
                                'output_format' => 'text',
                                'compilation_level' => 'SIMPLE_OPTIMIZATIONS',//'ADVANCED_OPTIMIZATIONS',//'SIMPLE_OPTIMIZATIONS'
                            ), null, '&');
                $URL            = 'http://closure-compiler.appspot.com/compile';
                $allowUrlFopen  = preg_match('/1|yes|on|true/i', ini_get('allow_url_fopen'));
                if($allowUrlFopen){
                    $contents = file_get_contents($URL, false, stream_context_create(array(
                            'http'          => array(
                                'method'        => 'POST',
                                'header'        => 'Content-type: application/x-www-form-urlencoded',
                                'content'       => $post_text,
                                'max_redirects' => 0,
                                'timeout'       => 15,
                            )
                    )));
                }elseif(defined('CURLOPT_POST')) {
                    $ch = curl_init($URL);
                    curl_setopt($ch, CURLOPT_POST, true);
                    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
                    curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-type: application/x-www-form-urlencoded'));
                    curl_setopt($ch, CURLOPT_POSTFIELDS, $post_text);
                    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);
                    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 15);
                    $contents = curl_exec($ch);
                    curl_close($ch);
                } else {
                    //"Could not make HTTP request: allow_url_open is false and cURL not available"
                    $contents = $text;
                }
                if($contents==false || (trim($contents)=='' && $text!='') || strtolower(substr(trim($contents),0,5))=='error' || strlen($contents)<=50){
                    //No HTTP response from server or empty response or error
                    $contents = $text;
                }
            }
            if(trim($contents)!=''){
                $contents = trim($contents);
                $f = fopen($file_cache, 'w');
                fwrite($f, $contents);
                fclose($f);
            }
        } else {
            touch($file_cache);     //in the future I will add a timetout to the cache
            $contents = file_get_contents($file_cache);
        }
        return $contents;
    }
    static function minify_html($text){
        if(isset($_GET['no_mini'])){
            return $text;
        }
        $file_cache     = strtolower(md5($text));
        $folder         = TMPPATH.'tmp_files'.DIRECTORY_SEPARATOR.substr($file_cache,0,2).DIRECTORY_SEPARATOR;
        if(!is_dir($folder))            @mkdir($folder, 0766, true);
        if(!is_dir($folder)){
            echo 'Impossible to create the cache folder:'.$folder;
            return 1;
        }
        $file_cache     = $folder.$file_cache.'_content.html';
        if(!file_exists($file_cache)){
            //get CSS and save it
            $search_css = '/<\s*style\b[^>]*>(.*?)<\s*\/style>/is';
            $ret = preg_match_all($search_css, $text, $tmps);
            $t_css = array();
            if($ret!==false && $ret>0){
                foreach($tmps as $k=>$v){
                    if($k>0){
                        foreach($v as $kk=>$vv){
                            $t_css[] = $vv;
                        }
                    }
                }
            }
            $css = format::minify_css(implode('\n', $t_css));

/*
            //get external JS and save it
            $search_js_ext = '/<\s*script\b.*?src=\s*[\'|"]([^\'|"]*)[^>]*>\s*<\s*\/script>/i';
            $ret = preg_match_all($search_js_ext, $text, $tmps);
            $t_js = array();
            if($ret!==false && $ret>0){
                foreach($tmps as $k=>$v){
                    if($k>0){
                        foreach($v as $kk=>$vv){
                            $t_js[] = $vv;
                        }
                    }
                }
            }
            $js_ext = $t_js;
*/
            //get inline JS and save it
            $search_js_ext  = '/<\s*script\b.*?src=\s*[\'|"]([^\'|"]*)[^>]*>\s*<\s*\/script>/i';
            $search_js      = '/<\s*script\b[^>]*>(.*?)<\s*\/script>/is';
            $ret            = preg_match_all($search_js, $text, $tmps);
            $t_js           = array();
            $js_ext         = array();
            if($ret!==false && $ret>0){
                foreach($tmps as $k=>$v){
                    if($k==0){
                        //let's check if we have a souce (src="")
                        foreach($v as $kk=>$vv){
                            if($vv!=''){
                                $ret = preg_match_all($search_js_ext, $vv, $ttmps);
                                if($ret!==false && $ret>0){
                                    foreach($ttmps[1] as $kkk=>$vvv){
                                        $js_ext[] = $vvv;
                                    }
                                }
                            }
                        }
                    } else {
                        foreach($v as $kk=>$vv){
                            if($vv!=''){
                                $t_js[] = $vv;
                            }
                        }
                    }
                }
            }
            $js = format::minify_js(implode('\n', $t_js));

            //get inline noscript and save it
            $search_no_js = '/<\s*noscript\b[^>]*>(.*?)<\s*\/noscript>/is';
            $ret = preg_match_all($search_no_js, $text, $tmps);
            $t_js = array();
            if($ret!==false && $ret>0){
                foreach($tmps as $k=>$v){
                    if($k>0){
                        foreach($v as $kk=>$vv){
                            $t_js[] = $vv;
                        }
                    }
                }
            }
            $no_js = implode('\n', $t_js);

            //remove CSS and JS
            $search = array(
                $search_js_ext,
                $search_css,
                $search_js,
                $search_no_js,
                '/\>[^\S ]+/s', //strip whitespaces after tags, except space
                '/[^\S ]+\</s', //strip whitespaces before tags, except space
                '/(\s)+/s',  // shorten multiple whitespace sequences
            );
            $replace = array(
                '',
                '',
                '',
                '',
                '>',
                '<',
                '\\1',
            );
            $buffer = preg_replace($search, $replace, $text);

            $append = '';
            //add CSS and JS at the bottom
            if(is_array($js_ext) && count($js_ext)>0){
                foreach($js_ext as $k=>$v){
                    $append .= '<script type="text/javascript" language="javascript" src="'.$v.'" ></script>';
                }
            }
            if($css!='')        $append .= '<style>'.$css.'</style>';
            if($js!=''){
                //remove weird '\n' strings
                $js = preg_replace('/[\s]*\\\n/', "\n", $js);
                $append .= '<script>'.$js.'</script>';
            }
            if($no_js!='')      $append .= '<noscript>'.$no_js.'</noscript>';
            $buffer = preg_replace('/(.*)(<\s*\/\s*body\s*>)(.*)/','\\1'.$append.'\\2\\3', $buffer);
            if(trim($buffer)!=''){
                $f = fopen($file_cache, 'w');
                fwrite($f, trim($buffer));
                fclose($f);
            }
        } else {
            touch($file_cache);     //in the future I will add a timetout to the cache
            $buffer = file_get_contents($file_cache);
        }

        return $buffer;
    }

}
?>

I have created 3 simple functions that will probably need to be optimized, but they do their job, they are part of a bigger class that I use to format code, dates, values, etc...:

to use it simply call:

echo format::minify_html($html_output);

here is the code (still in beta, but so far haven't had many issues with it)

<?php
class format(){
    static function minify_css($text){
        $from   = array(
        //                  '%(#|;|(//)).*%',               // comments:  # or //
            '%/\*(?:(?!\*/).)*\*/%s',       // comments:  /*...*/
            '/\s{2,}/',                     // extra spaces
            "/\s*([;{}])[\r\n\t\s]/",       // new lines
            '/\\s*;\\s*/',                  // white space (ws) between ;
            '/\\s*{\\s*/',                  // remove ws around {
            '/;?\\s*}\\s*/',                // remove ws around } and last semicolon in declaration block
            //                  '/:first-l(etter|ine)\\{/',     // prevent triggering IE6 bug: http://www.crankygeek.com/ie6pebug/
        //                  '/((?:padding|margin|border|outline):\\d+(?:px|em)?) # 1 = prop : 1st numeric value\\s+/x',     // Use newline after 1st numeric value (to limit line lengths).
        //                  '/([^=])#([a-f\\d])\\2([a-f\\d])\\3([a-f\\d])\\4([\\s;\\}])/i',
        );
        $to     = array(
        //                  '',
            '',
            ' ',
            '$1',
            ';',
            '{',
            '}',
            //                  ':first-l$1 {',
        //                  "$1\n",
        //                  '$1#$2$3$4$5',
        );
        $text   = preg_replace($from,$to,$text);
        return $text;
    }
    static function minify_js($text){
        $file_cache     = strtolower(md5($text));
        $folder         = TMPPATH.'tmp_files'.DIRECTORY_SEPARATOR.substr($file_cache,0,2).DIRECTORY_SEPARATOR;
        if(!is_dir($folder))            @mkdir($folder, 0766, true);
        if(!is_dir($folder)){
            echo 'Impossible to create the cache folder:'.$folder;
            return 1;
        }
        $file_cache     = $folder.$file_cache.'_content.js';
        if(!file_exists($file_cache)){
            if(strlen($text)<=100){
                $contents = $text;
            } else {
                $contents = '';
                $post_text = http_build_query(array(
                                'js_code' => $text,
                                'output_info' => 'compiled_code',//($returnErrors ? 'errors' : 'compiled_code'),
                                'output_format' => 'text',
                                'compilation_level' => 'SIMPLE_OPTIMIZATIONS',//'ADVANCED_OPTIMIZATIONS',//'SIMPLE_OPTIMIZATIONS'
                            ), null, '&');
                $URL            = 'http://closure-compiler.appspot.com/compile';
                $allowUrlFopen  = preg_match('/1|yes|on|true/i', ini_get('allow_url_fopen'));
                if($allowUrlFopen){
                    $contents = file_get_contents($URL, false, stream_context_create(array(
                            'http'          => array(
                                'method'        => 'POST',
                                'header'        => 'Content-type: application/x-www-form-urlencoded',
                                'content'       => $post_text,
                                'max_redirects' => 0,
                                'timeout'       => 15,
                            )
                    )));
                }elseif(defined('CURLOPT_POST')) {
                    $ch = curl_init($URL);
                    curl_setopt($ch, CURLOPT_POST, true);
                    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
                    curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-type: application/x-www-form-urlencoded'));
                    curl_setopt($ch, CURLOPT_POSTFIELDS, $post_text);
                    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);
                    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 15);
                    $contents = curl_exec($ch);
                    curl_close($ch);
                } else {
                    //"Could not make HTTP request: allow_url_open is false and cURL not available"
                    $contents = $text;
                }
                if($contents==false || (trim($contents)=='' && $text!='') || strtolower(substr(trim($contents),0,5))=='error' || strlen($contents)<=50){
                    //No HTTP response from server or empty response or error
                    $contents = $text;
                }
            }
            if(trim($contents)!=''){
                $contents = trim($contents);
                $f = fopen($file_cache, 'w');
                fwrite($f, $contents);
                fclose($f);
            }
        } else {
            touch($file_cache);     //in the future I will add a timetout to the cache
            $contents = file_get_contents($file_cache);
        }
        return $contents;
    }
    static function minify_html($text){
        if(isset($_GET['no_mini'])){
            return $text;
        }
        $file_cache     = strtolower(md5($text));
        $folder         = TMPPATH.'tmp_files'.DIRECTORY_SEPARATOR.substr($file_cache,0,2).DIRECTORY_SEPARATOR;
        if(!is_dir($folder))            @mkdir($folder, 0766, true);
        if(!is_dir($folder)){
            echo 'Impossible to create the cache folder:'.$folder;
            return 1;
        }
        $file_cache     = $folder.$file_cache.'_content.html';
        if(!file_exists($file_cache)){
            //get CSS and save it
            $search_css = '/<\s*style\b[^>]*>(.*?)<\s*\/style>/is';
            $ret = preg_match_all($search_css, $text, $tmps);
            $t_css = array();
            if($ret!==false && $ret>0){
                foreach($tmps as $k=>$v){
                    if($k>0){
                        foreach($v as $kk=>$vv){
                            $t_css[] = $vv;
                        }
                    }
                }
            }
            $css = format::minify_css(implode('\n', $t_css));

/*
            //get external JS and save it
            $search_js_ext = '/<\s*script\b.*?src=\s*[\'|"]([^\'|"]*)[^>]*>\s*<\s*\/script>/i';
            $ret = preg_match_all($search_js_ext, $text, $tmps);
            $t_js = array();
            if($ret!==false && $ret>0){
                foreach($tmps as $k=>$v){
                    if($k>0){
                        foreach($v as $kk=>$vv){
                            $t_js[] = $vv;
                        }
                    }
                }
            }
            $js_ext = $t_js;
*/
            //get inline JS and save it
            $search_js_ext  = '/<\s*script\b.*?src=\s*[\'|"]([^\'|"]*)[^>]*>\s*<\s*\/script>/i';
            $search_js      = '/<\s*script\b[^>]*>(.*?)<\s*\/script>/is';
            $ret            = preg_match_all($search_js, $text, $tmps);
            $t_js           = array();
            $js_ext         = array();
            if($ret!==false && $ret>0){
                foreach($tmps as $k=>$v){
                    if($k==0){
                        //let's check if we have a souce (src="")
                        foreach($v as $kk=>$vv){
                            if($vv!=''){
                                $ret = preg_match_all($search_js_ext, $vv, $ttmps);
                                if($ret!==false && $ret>0){
                                    foreach($ttmps[1] as $kkk=>$vvv){
                                        $js_ext[] = $vvv;
                                    }
                                }
                            }
                        }
                    } else {
                        foreach($v as $kk=>$vv){
                            if($vv!=''){
                                $t_js[] = $vv;
                            }
                        }
                    }
                }
            }
            $js = format::minify_js(implode('\n', $t_js));

            //get inline noscript and save it
            $search_no_js = '/<\s*noscript\b[^>]*>(.*?)<\s*\/noscript>/is';
            $ret = preg_match_all($search_no_js, $text, $tmps);
            $t_js = array();
            if($ret!==false && $ret>0){
                foreach($tmps as $k=>$v){
                    if($k>0){
                        foreach($v as $kk=>$vv){
                            $t_js[] = $vv;
                        }
                    }
                }
            }
            $no_js = implode('\n', $t_js);

            //remove CSS and JS
            $search = array(
                $search_js_ext,
                $search_css,
                $search_js,
                $search_no_js,
                '/\>[^\S ]+/s', //strip whitespaces after tags, except space
                '/[^\S ]+\</s', //strip whitespaces before tags, except space
                '/(\s)+/s',  // shorten multiple whitespace sequences
            );
            $replace = array(
                '',
                '',
                '',
                '',
                '>',
                '<',
                '\\1',
            );
            $buffer = preg_replace($search, $replace, $text);

            $append = '';
            //add CSS and JS at the bottom
            if(is_array($js_ext) && count($js_ext)>0){
                foreach($js_ext as $k=>$v){
                    $append .= '<script type="text/javascript" language="javascript" src="'.$v.'" ></script>';
                }
            }
            if($css!='')        $append .= '<style>'.$css.'</style>';
            if($js!=''){
                //remove weird '\n' strings
                $js = preg_replace('/[\s]*\\\n/', "\n", $js);
                $append .= '<script>'.$js.'</script>';
            }
            if($no_js!='')      $append .= '<noscript>'.$no_js.'</noscript>';
            $buffer = preg_replace('/(.*)(<\s*\/\s*body\s*>)(.*)/','\\1'.$append.'\\2\\3', $buffer);
            if(trim($buffer)!=''){
                $f = fopen($file_cache, 'w');
                fwrite($f, trim($buffer));
                fclose($f);
            }
        } else {
            touch($file_cache);     //in the future I will add a timetout to the cache
            $buffer = file_get_contents($file_cache);
        }

        return $buffer;
    }

}
?>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文