En este post os dejo una clase PHP para comprimir recursos CSS, JS y HTML de forma dinámica. De esta manera, la clase minificará los recursos en la ejecución de la página para mostrarlos ya comprimidos en linea en el propio html, sin tener que comprimir nosotros los propios archivos css, js, etc… Así podremos seguir trabajando sobre ellos cómodamente sin minificar.
Esta clase trabaja con el módulo PHP compress.zlib que permite leer y escribir ficheros comprimidos con gzip (.gz) de forma transparente. En el caso de CSS y JS, les pasaríamos en un array el listado de links de los archivos a minificar con los métodos processListCSS y processListJS.
Según nuestras necesidades, podemos modificar los métodos para que minifique el código css o javascript pasado como una variable string en vez de leer un archivo externo, que los combine en una misma etiqueta <style> o <script> o crear archivos con el código comprimido y llamarlos en el HTML.
¡Espero que os guste!
class Optimizer{ /* Minificar HTML */ public function minifyHTML( $buffer ) { $this->zlibCompression(); if ( $this->isHTML( $buffer ) ) { $pattern = "/<script[^>]*>(.*?)<\/script>/is"; preg_match_all( $pattern, $buffer, $matches, PREG_SET_ORDER, 0 ); foreach ( $matches as $match ) { $pattern = "/(<script[^>]*>)(" . preg_quote( $match[1], '/' ) . ")(<\/script>)/is"; $compress = self::compressJS($match[1]); $buffer = preg_replace( $pattern, '$1' . $compress . '$3', $buffer ); } $pattern = "/<style[^>]*>(.*?)<\/style>/is"; preg_match_all( $pattern, $buffer, $matches, PREG_SET_ORDER, 0 ); foreach ( $matches as $match ) { $pattern = "/(<style[^>]*>)(" . preg_quote( $match[1], '/' ) . ")(<\/style>)/is"; $compress = self::compressCSS( $match[1] ); $buffer = preg_replace( $pattern, '$1' . $compress . '$3', $buffer ); } $buffer = preg_replace(array('/<!--[^\[](.*)[^\]]-->/Uuis', "/[[:blank:]]+/u", '/\s+/u'), array('', ' ', ' '), str_replace(array("\n", "\r", "\t"), '', $buffer)); } return $buffer; } /* Minificar CSS */ public function minifyCSS( $buffer ) { $this->zlibCompression(); return preg_replace( array( '#\/\*[\s\S]*?\*\/#', '/\s+/' ), array( '', ' ' ), str_replace( array( "\n", "\r", "\t"), '', $buffer ) ); } /* Minificar Javascript */ public function minifyJS( $buffer ) { $this->zlibCompression(); return str_replace( array( "\n", "\r", "\t" ), '', preg_replace( array( '#\/\*[\s\S]*?\*\/|([^:]|^)\/\/.*$#m', '/\s+/'), array( '', ' ' ), $buffer ) ); } /* Procesar listado CSS */ public function processListCSS( $arrayCSS ) { if( ! is_array( $arrayCSS ) ) { return false; } $output = ''; foreach ( $arrayCSS as $css ) { $output .= '<style>'.$this->minifyCSS( file_get_contents( $css['url'] ) ).'</style>'; } return $output; } /* Procesar listado Javascript */ public function processListJS( $arrayJS ) { if( ! is_array( $arrayJS ) ) { return false; } $output = ''; foreach ( $arrayJS as $js ) { $output .= '<script>'.$this->minifyJS( file_get_contents( $js['url'] ) ).'</script>'; } return $output; } /* Comprobar si es HTML */ private function isHTML( $string ) { return preg_match( '/<html.*>/', $string ) ? true : false; } /* Zlib compression */ private function zlibCompression() { if( ini_get( 'zlib.output_compression' ) ) { ini_set( "zlib.output_compression", 1 ); ini_set( "zlib.output_compression_level", "9" ); } } }
Hola,
Me parece interesante, soy novato y tengo la duda de cómo implementar esta clase.
Saludos,
Jaime
Hola Jaime, gracias por tu comentario.
Yo suelo llamar a la clase en el archivo header.php, donde pinto todas las cabeceras y meta-tags del HTML. Creo un array con las rutas de los archivos css y js y los paso por las funciones processListJS y processListCSS. Por ejemplo:
require dirname( __FILE__ ) . ‘/class. Optimizer.php’;
$optimizer = new Optimizer();
$arrayJS = array(
‘midominio.com/assets/js/archivo.js’,
‘midominio.com/assets/js/archivo2.js’
);
$optimizer->processListJS( $arrayJS );