2010-06-22 16 views
6

Estoy usando gzip para comprimir mis archivos html/php junto con js/css/etc. Esto reduce la carga útil bastante bien pero también quiero 'minify' mi marcado de ambas páginas .html y .php. Idealmente, me gustaría controlar esto desde un archivo .htaccess (donde también hago el gzipping) en lugar de tener que incluir php en cada archivo.Minificar HTML/PHP

me gustaría que la salida sea igual que la de http://google.com o http://www.w3-edge.com/wordpress-plugins/w3-total-cache/ y http://css-tricks.com (ambos producidos por W3 Total Cache Plugin for WordPress).

¿Alguien puede recomendar una buena manera de hacerlo?

Respuesta

8

Mirando los ejemplos, minimizar el resultado HTML no hace casi nada. Piénselo: Minificar es excelente para Javascript, que usa muchos nombres de variables y funciones repetitivas, ya que una de las cosas principales que minimiza es acortarlos y todas las referencias a ellos.

El marcado HTML, por otro lado, no tiene ningún concepto de variables o funciones. La mayor parte del peso de la página proviene del marcado real y el contenido. Esto no puede ser minimizado. Incluso las variables de formulario deben dejarse de lado, ya que deben tener sus valores originales para ser procesados ​​correctamente por el servidor.

Gzipping ya comprimirá los espacios en blanco de manera muy eficiente. En HTML, esto es realmente todo lo que se puede hacer.

Además, no se aplica la minimización de PHP, porque aunque tiene variables y funciones, nunca se envía al cliente. Acortar los nombres no tiene ningún beneficio de rendimiento para algo compilado en el servidor.

Si está decidido a minificar su html, revise el código fuente del plugin de WordPress que lo hace. Esa es la belleza de la fuente abierta. Sin embargo, sospecho que las ganancias serán insignificantes en comparación con Gzipping.

+8

Yo no dirijo minifying PHP, ya que no se aplica. El código PHP nunca se envía al cliente. –

+0

@Peter Anselmo: Debe agregar ese comentario a su respuesta. – Powerlord

+1

Creo que se refería a la salida HTML de páginas PHP. –

5

Peter Anselmo ha confundido la minificación por ofuscación. En la ofuscación del código, el código se minimiza y las variables se renombran a nombres arbitrarios de menor longitud. La minimización es simplemente la práctica de reducir el tamaño del código, como la eliminación de espacios en blanco, sin alterar los valores, nombres o sintaxis del código.

Peter Anselmo también se equivoca al minimizar los resultados de marcado en un ahorro insignificante. Esta página, por ejemplo, muestra un ahorro de 18.31% y fue bastante ordenado para empezar. Claramente, nunca ha puesto a prueba su opinión antes de publicarla. Puede ver los ahorros usted mismo usando la herramienta Pretty Diff en http://prettydiff.com/

Puede intentar realizar una ingeniería inversa del motor de minificación utilizado por Pretty Diff para ejecutar desde PHP. Ese código y la documentación acompañada se pueden encontrar en: prettydiff.com/markupmin.js

+4

¡Normalmente la ofuscación es más que eso! Dijo que minimizar ganancias sería insignificante * en comparación con gzipping *. De una prueba rápida que es 18% vs 75%. Ahora, la compresión de la versión minimizada ahorrará un poco más, otro 1-2%, pero la mayor parte del camino la tienes solo con el gzip. – Rup

+1

Sí, sacaste por completo mi frase fuera de contexto, que se refería a minificar además de gzipping. Su herramienta diff bastante no evalúa este escenario, solo evalúa código descomprimido vs código comprimido minimizado. Además, muchos minificadores (incluidos el compresor YUI, el Compilador de cierre y el Encomiendas) acortan los nombres de las variables. Tal vez debería haber sido más claro acerca de la minificación frente a la ofuscación en beneficio de OP, pero todavía no veo ninguna necesidad de editar mi publicación. –

+0

Debería haber sido un poco más claro, pero sí me refería simplemente a la simple minificación y eliminación de espacios en blanco en lugar de ofuscación. Un buen método que he encontrado es usar buffering de salida con obstart() que simplemente se puede llamar en el encabezado y usar en combinación con algunas expresiones regulares para quitar todo lo innecesario del marcado antes de enviarlo al navegador. Con respecto a las páginas de PHP, sí, me refería al marcado de esas páginas. La herramienta prettydiff es bastante útil. ¡Gracias por el consejo! – Ian

3

He creado 3 funciones simples que probablemente necesitarán ser optimizadas, pero hacen su trabajo, son parte de una clase más grande que yo usar para formatear código, fechas, valores, etc.:

de usar simplemente llamar:

echo format::minify_html($html_output); 

aquí está el código (todavía en fase beta, pero hasta el momento no han tenido muchos problemas con él)

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

Creo que la mayor utilidad de optimizar HTML en PHP es que HTML es (normalmente) dinámico, así que aunque puedo minimizar JS y CSS de, digamos, un script de compilación bash, no puedo hacerlo en HTML. Es decir, es algo que debería hacerse en cada solicitud. –

0

No es un país libre biblioteca (licencia BSD) para PHP llamada PHPWee que satisface sus necesidades

será minify su HTML, XHTML, HTML 5, CSS y JS de salida de la siguiente manera:

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

el repositorio en Github es:

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

+0

He intentado trabajar con él, todavía tiene un largo camino por recorrer, empiece con el uso de ' Wazime

Cuestiones relacionadas