2010-06-22 7 views
6

Tôi đang sử dụng gzip để nén các tệp html/php của mình cùng với js/css/etc. Điều này làm giảm tải trọng khá độc đáo nhưng tôi cũng muốn 'giảm thiểu' đánh dấu của tôi cả hai trang .html và .php. Lý tưởng nhất là tôi muốn kiểm soát điều này từ một tập tin .htaccess (nơi tôi cũng làm gzipping) thay vì phải bao gồm php cho mỗi tập tin.Giảm bớt HTML/PHP

Tôi muốn đầu ra giống như của http://google.com hoặc http://www.w3-edge.com/wordpress-plugins/w3-total-cache/http://css-tricks.com (cả hai được tạo bởi plugin W3 Total Cache cho WordPress).

Bất kỳ ai cũng có thể đề xuất cách tốt để thực hiện việc này.

Trả lời

8

Nhìn vào các ví dụ, giảm thiểu đầu ra HTML hầu như không có gì. Hãy suy nghĩ về nó: Giảm thiểu là rất tốt cho Javascript trong đó sử dụng nhiều biến lặp lại và tên chức năng, là một trong những điều chính làm giảm bớt là rút ngắn chúng và tất cả các tài liệu tham khảo cho họ.

Đánh dấu HTML, mặt khác, không có khái niệm về biến hoặc hàm. Phần lớn trọng lượng của trang là từ đánh dấu và nội dung thực tế. Điều này không thể được rút ngắn. Ngay cả các biến mẫu cần phải được để lại một mình vì chúng phải có các giá trị ban đầu của chúng được xử lý chính xác bởi máy chủ.

Gzipping sẽ đã nén khoảng trắng rất hiệu quả. Trong HTML, điều này thực sự là tất cả những gì có thể được thực hiện.

Ngoài ra, việc rút gọn PHP không áp dụng, bởi vì mặc dù nó có các biến và chức năng, nó không bao giờ được gửi tới máy khách. Việc rút ngắn tên không có lợi ích về hiệu suất cho một số thứ được biên dịch trên máy chủ.

Nếu bạn được xác định là rút gọn html của mình, hãy kiểm tra mã nguồn cho plugin WordPress thực hiện điều đó. Đó là vẻ đẹp của nguồn mở. Tuy nhiên, tôi nghi ngờ lợi nhuận sẽ không đáng kể so với Gzipping.

+8

tôi không giải quyết rút gọn PHP, vì nó không được áp dụng. Mã PHP không bao giờ được gửi đến máy khách. –

+0

@Peter Anselmo: Bạn nên thêm nhận xét đó vào câu trả lời của mình. – Powerlord

+1

Tôi nghĩ anh ấy có nghĩa là đầu ra HTML của các trang PHP. –

5

Peter Anselmo đã giảm thiểu sự nhầm lẫn để làm xáo trộn. Trong mã obfuscation mã được rút gọn và các biến được đổi tên thành tên tùy ý chiều dài ngắn nhất. Giảm thiểu chỉ đơn thuần là thực hành giảm kích thước mã, chẳng hạn như xóa không gian trắng, mà không thay đổi các giá trị, tên hoặc cú pháp mã.

Peter Anselmo cũng sai khi rút ngắn kết quả đánh dấu bằng một khoản tiết kiệm không đáng kể. Trang này, ví dụ, cho thấy một khoản tiết kiệm 18,31% và nó đã được khá gọn gàng để bắt đầu với. Rõ ràng, anh chưa bao giờ thử nghiệm ý kiến ​​của mình trước khi đưa nó ra khỏi đó. Bạn có thể tự mình tiết kiệm chi phí bằng cách sử dụng công cụ Pretty Diff tại http://prettydiff.com/

Bạn có thể tìm cách đảo ngược công cụ rút gọn được Pretty Diff sử dụng để thực thi từ PHP. Mã đó và tài liệu đi kèm có thể được tìm thấy tại: prettydiff.com/markupmin.js

+4

Thông thường obfuscation là nhiều hơn thế! Anh ta nói rằng việc giảm thiểu lợi nhuận sẽ không đáng kể * so với gzipping *. Từ một thử nghiệm nhanh chóng là 18% so với 75%. Bây giờ gzipping các phiên bản minified sẽ tiết kiệm được nhiều hơn một chút - 1-2% khác - nhưng bạn có hầu hết các cách có với gzip một mình. – Rup

+1

Có, bạn hoàn toàn mất cụm từ của tôi trong bối cảnh đó là liên quan đến khai thác ngoài việc gzipping. Công cụ của bạn khá khác không đánh giá kịch bản này, nó chỉ đánh giá mã không được sửa đổi so với mã ucompressed được rút gọn. Ngoài ra, nhiều bộ lọc (bao gồm cả máy nén YUI, Bộ đóng gói đóng gói và Trình đóng gói) DO rút ngắn tên biến. Có lẽ tôi nên rõ ràng hơn về việc rút gọn và làm xáo trộn vì lợi ích của OP, nhưng tôi vẫn không thấy cần chỉnh sửa bài đăng của mình. –

+0

Tôi nên có một chút rõ ràng hơn nhưng có tôi đã làm có nghĩa là chỉ đơn giản hóa minification và tước của khoảng trắng hơn là obfuscation. Một phương pháp tốt mà tôi đã tìm thấy là sử dụng bộ đệm đầu ra với obstart() có thể được gọi trong tiêu đề và được sử dụng kết hợp với một số biểu thức chính quy để loại bỏ mọi thứ không cần thiết khỏi đánh dấu trước khi gửi đến trình duyệt. Liên quan đến các trang PHP, vâng tôi chỉ có nghĩa là đánh dấu các trang đó. Công cụ prettydiff khá hữu ích. Cảm ơn vì tiền hỗ trợ! – Ian

3

Tôi đã tạo 3 hàm đơn giản có thể cần được tối ưu hóa, nhưng chúng thực hiện công việc của mình, chúng là một phần của lớp lớn hơn mà tôi sử dụng để định dạng mã, ngày, giá trị, v.v ...:

để sử dụng nó chỉ cần gọi:

echo format::minify_html($html_output); 

đây là mã (vẫn còn trong phiên bản beta, nhưng cho đến nay vẫn chưa có nhiều vấn đề với nó)

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

} 
?> 
+0

Tôi nghĩ rằng tính hữu ích lớn nhất của việc tối ưu hóa HTML trong PHP là HTML (thường) động, vì vậy trong khi tôi có thể rút gọn JS và CSS từ, một tập lệnh bash build, tôi không thể làm điều đó với HTML. Đó là, đó là một cái gì đó cần phải được thực hiện mỗi yêu cầu. –

0

Có một miễn phí thư viện (giấy phép BSD) cho PHP được gọi là PHPWee đáp ứng các yêu cầu của bạn

Nó sẽ giảm bớt đầu ra HTML, XHTML, HTML5, CSS và JS như sau:

require_once ("phpwee-php-minifier/phpwee.php"); 
$html = file_get_contents("searchturbine.com/php/phpwee"); 
$minified_html = PHPWee\Minify::html($html); 

Các repo là trên Github:

https://github.com/searchturbine/phpwee-php-minifier

+0

Tôi đã cố gắng làm việc với nó, bạn vẫn còn một chặng đường dài để đi, bắt đầu bằng cách sử dụng ' Wazime