Сократить HTML / PHP - PullRequest
       35

Сократить HTML / PHP

7 голосов
/ 22 июня 2010

Я использую gzip для сжатия моих html / php файлов вместе с js / css / etc. Это довольно неплохо уменьшает полезную нагрузку, но я также хочу «минимизировать» мою разметку страниц .html и .php. В идеале я хотел бы контролировать это из файла .htaccess (где я также делаю gzipping), а не из-за необходимости включать php в каждый файл.

Я бы хотел, чтобы выходные данные были такими, как http://google.com или http://www.w3 -edge.com / wordpress-plugins / w3-total-cache / и http://css -tricks.com (оба созданы плагином W3 Total Cache для WordPress).

Может кто-нибудь порекомендовать хороший способ сделать это.

Ответы [ 3 ]

8 голосов
/ 22 июня 2010

Глядя на примеры, минимизация вывода HTML почти ничего не делает.Подумайте об этом: Minifying отлично подходит для Javascript, который использует много повторяющихся имен переменных и функций, так как одной из основных функций minifying является сокращение их и всех ссылок на них.

HTML-разметка, с другой стороны, имеетнет понятия переменных или функций.Большая часть веса страницы основана на фактической разметке и содержании.Это не может быть уменьшено.Даже переменные формы должны быть оставлены в покое, так как они должны иметь свои исходные значения для правильной обработки сервером.

Gzipping уже очень эффективно сжимает пустое пространство.В HTML это действительно все, что можно сделать.

Кроме того, минимизация PHP не применяется, потому что, хотя она имеет переменные и функции, она никогда не отправляется клиенту.Сокращение имен не дает никакого преимущества в производительности для чего-то, скомпилированного на сервере.

Если вы полны решимости минимизировать ваш HTML, проверьте исходный код подключаемого модуля WordPress, который это делает.В этом красота открытого исходного кода.Тем не менее, я подозреваю, что выигрыш будет незначительным по сравнению с Gzipping.

5 голосов
/ 24 июня 2010

Питер Ансельмо запутал минимизацию для запутывания.При запутывании кода код минимизируется, а переменные переименовываются в произвольные имена наименьшей длины.Минификация - это просто практика уменьшения размера кода, такого как удаление пробелов, без изменения значений, имен или синтаксиса кода.

Питер Ансельмо также не прав, что минимизация разметки приводит к незначительной экономии.Эта страница, например, показывает экономию 18,31%, и это было довольно аккуратно с самого начала.Очевидно, что он никогда не проверял свое мнение, прежде чем высказывать его там.Вы можете сами увидеть экономию средств, используя инструмент Pretty Diff по адресу http://prettydiff.com/

. Вы можете попытаться реверсировать механизм минимизации, используемый Pretty Diff для выполнения из PHP.Этот код и сопровождающую документацию можно найти по адресу: prettydiff.com/markupmin.js

3 голосов
/ 22 октября 2012

Я создал 3 простых функции, которые, вероятно, нужно будет оптимизировать, но они выполняют свою работу, они являются частью большего класса, который я использую для форматирования кода, дат, значений и т. Д.:

, чтобы использовать его, просто позвоните:

echo format::minify_html($html_output);

вот код (все еще в бета-версии, но до сих пор не было много проблем с ним)

<?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;
    }

}
?>
...