El tiempo de carga de una página web es muy importante para nuestro posicionamiento SEO.
Una de las formas de disminuir esta carga es reduciendo el tamaño de nuestros scripts y hojas de estilos (CSS).

¿Por qué es tan importante el tiempo de carga de nuestra web?

Es importante que las hojas de estilos se descarguen rápidamente para que nuestro navegador aplique los estilos lo antes posible y por ello se recomienda que no ocupen más de 100 kb por fichero CSS. Además cuando un visitante entra a nuestra página web y esta tarda demasiado en cargar (5-6 segundos o más) lo más probable es que opte por salirse de la web y busqué otra. El tiempo de carga también es un factor importante para el posicionamiento web (SEO). Aunque parezca que no tiene importancia reducir un fichero CSS o script de 100 kb a 60 kb por ejemplo, cuando nuestra página web crezca se verá afectado el rendimiento considerablemente, aunque lo recomendable sería comprimir tanto los archivos CSS, JavaScripts, HTML e imágenes. También sería recomendable reducir lo máximo posible la cantidad de archivos CSS y scripts para evitar peticiones HTTP y conexiones innecesarias a nuestro servidor, cuantas menos conexiones menos tardará en cargar la página web completamente.

Comprobar el tiempo de carga de nuestra página web

Google nos ofrece una herramienta gratuita llamada “PageSpeed Insights” para comprobar y optimizar la velocidad de carga de los diferentes contenidos de nuestro sitio web tanto en la versión móvil como en la versión de ordenador.

Existen diferentes herramientas online para comprimir nuestros archivos CSS:

Y también para comprimir nuestros archivos JavaScript:


Otras alternativas

Podemos usar el editor “Sublime Text 2” e instalar el paquete “YUI Compressor” desde Preferences > Package Control.
Una vez instalado tan solo debemos abrir la hoja de estilos o código JavaScript que queramos comprimir y posteriormente presionamos la tecla F7 o las teclas Control + B y se generará un nuevo archivo con el mismo nombre pero con la terminación .min (abreviación de minify) agregado.


Minify CSS

Para no depender de herramientas online y poder integrar nuestro propio compresor de hojas de estilos en nuestros proyectos web hemos desarrollado una clase en PHP llamada “Minify CSS” para realizar tanto la compresión como la descompresión de hojas de estilos (CSS) y posteriormente sustituirlos en nuestra página web o incluso implementar y adaptar esta clase en cualquier CMS.

NOTA: Es importante guardar SIEMPRE las hojas de estilos originales ya que una vez comprimidas ciertas partes serán irrecuperables como los comentarios, entre otros.

minifycss.class.php

<?php

/*
	AUTHOR: SecurityNull
	VERSION: 1.0.0
	WEBSITE: www.securitynull.net
	DATE: 23/10/2014
	CONTACT: projects@securitynull.net
	LICENSE: GNU/GPL
	MORE INFO: http://www.securitynull.net/comprime-tus-hojas-de-estilos-css-minifycss-source
*/

class Minify_CSS {

	/* CONSTS */
	const MINIFY_LOW = 1;
	const MINIFY_HIGHT = 2;
	const MINIFY_MAXIMUM = 3;

	/* VARS */
	private $css = NULL;

	/* GETTERS */
	function __construct($css) {
		$this->css = $css;
	}

	public function getProcessedCSS() {
		return $this->css;
	}

	/* PUBLIC FUNCTIONS */
	public static function compressCSS($css_decompressed, $level = self::MINIFY_HIGHT) {
		if (!empty($css_decompressed)) {
			$minify_css = new Minify_CSS($css_decompressed);

			switch ($level) {
				case self::MINIFY_LOW:
					$minify_css->removeComments();
					$minify_css->removeWhiteLines();
					$minify_css->removeSemicolons();
					$minify_css->removeWhiteSpaces();
					$minify_css->tabCode();
					break;
				case self::MINIFY_HIGHT:
					$minify_css->removeComments();
					$minify_css->removeWhiteLines();
					$minify_css->removeSemicolons();
					$minify_css->removeWhiteSpaces();
					break;
				case self::MINIFY_MAXIMUM:
					$minify_css->removeComments();
					$minify_css->removeWhiteLines();
					$minify_css->removeSemicolons();
					$minify_css->removeWhiteSpaces();
					$minify_css->removeBreakLines();
					$minify_css->removeExtraWhiteSpaces();
					$minify_css->minimizeHexColors();
					break;				
				default:
					break;
			}

			return $minify_css->getProcessedCSS();
		} else
			return false;
	}

	public static function decompressCSS($css_compressed) {
		if (!empty($css_compressed)) {
			$minify_css = new Minify_CSS($css_compressed);
			$minify_css->tabCode();
			
			return $minify_css->getProcessedCSS();
		}
	}

	/* PRIVATE FUNCTIONS */
	private function removeWhiteLines() {
		$this->css = preg_replace('/^[ \t]*[\r\n]+/m', '', $this->css);
	}

	private function removeBreakLines() {
		$this->css = preg_replace('/[\r\n]+/', '', $this->css);
	}

	private function removeComments() {
		$this->css = preg_replace('#/\*.*?\*/#s', '', $this->css);
	}

	private function removeWhiteSpaces() {
		$this->css = preg_replace('/\s*([{}|:;,])\s+/', '$1', $this->css);
		$this->css = preg_replace('/\s*({)/', '$1', $this->css);
		$this->css = preg_replace('/\s\s+(.*)/', '$1', $this->css);
		$this->css = preg_replace('/\\s*;\\s*/', ';', $this->css);
		$this->css = preg_replace('/\\s*([,}])\\s*/', '$1', $this->css);
		$this->css = preg_replace('/\\s*(\);|})\\s*/', "$1\n", $this->css);
	}

	private function removeExtraWhiteSpaces() {
        // Remove white spaces around urls
        $this->css = preg_replace('/url\\(\\s*([^\\)]+?)\\s*\\)/', 'url($1)', $this->css);
        // Remove white spaces between rules and colons
        $this->css = preg_replace('/\\s*([{;])\\s*([\\*_]?[\\w\\-]+)\\s*:\\s*(\\b|[#\'"-])/', '$1$2:$3', $this->css);
        // Remove white spaces in selectors
        $this->css = preg_replace_callback('/(?:\\s*[^~>+,\\s]+\\s*[,>+~])+\\s*[^~>+,\\s]+{/' ,array($this, '__selectors'), $this->css);
        // Remove spaces between font families
        $this->css = preg_replace_callback('/font-family:([^;}]+)([;}])/', array($this, '__fontFamily'), $this->css);
        // Remove spaces between import urls
        $this->css = preg_replace('/@import\\s+url/', '@import url', $this->css);
        // Replace any white space involving newlines with a single newline
        //$this->css = preg_replace('/[ \\t]*\\n+\\s*/', "\n", $this->css);
	}

	private function removeSemicolons() {
		$this->css = preg_replace('/\\s*{\\s*/', '{', $this->css);
        $this->css = preg_replace('/;?\\s*}\\s*/', '}', $this->css);
	}

	private function minimizeHexColors() {
		$this->css = preg_replace('/([^=])#([a-f\\d])\\2([a-f\\d])\\3([a-f\\d])\\4([\\s;\\}])/i', '$1#$2$3$4$5', $this->css);
	}

	private function tabCode() {
		$this->css = preg_replace('/\\s*({)\\s*/', "$1\n", $this->css);
		$this->css = preg_replace('/\\s*(\);)\\s*/', "$1\n\n", $this->css);
		$this->css = preg_replace_callback('/\\s*(.*)[{]/', array($this, "__breakSelectors"), $this->css);
		$this->css = preg_replace('/\\s*(})\\s*/', "\n$1\n\n", $this->css);
		$this->css = preg_replace('/\\s*([{;])\\s*([\\*_]?[\\w\\-]+)\\s*:\\s*(\\b|[#\'"-])/', "$1\n\t$2:$3", $this->css);
	}

	/* CALLBACKS */
	protected function __breakSelectors($m) {
        return preg_replace('/\\s*([,])\\s*/', "$1\n", $m[0]);
    }

    protected function __fontFamily($m) {
        $m[1] = preg_replace('/\\s*("[^"]+"|\'[^\']+\'|[\\w\\-]+)\\s*/x', '$1', $m[1]);
        return 'font-family:' . $m[1] . $m[2];
    }

    protected function __selectors($m) {
        // Remove ws around the combinators
        return preg_replace('/\\s*([,>+~])\\s*/', '$1', $m[0]);
    }

}

?>
Minify CSS Demo Minify CSS Demo

Descargar proyecto

La clase cuenta con 3 niveles de compresión:

  • Bajo: En este nivel tan solo se eliminan los comentarios, el punto y coma (;) de la última propiedad de cada bloque, espacios y líneas en blanco. Esta opción tabula el código para que sea legible.
  • Alto: Realiza lo mismo que en el nivel bajo pero además elimina las tabulaciones, haciendo que cada bloque este en una línea.
  • Máximo: Realiza todo lo anterior, genera todo el CSS en una única línea y como extra comprime los colores en hexadecimal (por ejemplo #ffffff sería #fff), elimina espacios no necesarios entre selectores, fuentes, urls…

Por ejemplo si comprimimos el siguiente archivo CSS:

html,
body {
	width: 100%;
	margin: 0 auto;
}

h1, h2, h3, h4, h5, h6 {
	font-size: 18px;
	font-family: 'arial';
}

div span {display: block; color: #ffffff; text-align: center;}

div + .background {
	background: #000000;
	-webkit-box-shadow: 1px 1px 5px #111111;
}

ul > li:fist-child {
	padding-top: 50px;
}

329 bytes

Nivel bajo

html,
body{
	width:100%;
	margin:0 auto
}

h1,
h2,
h3,
h4,
h5,
h6{
	font-size:18px;
	font-family:'arial'
}

div span{
	display:block;
	color:#ffffff;
	text-align:center
}

div+.background{
	background:#000000;
	-webkit-box-shadow:1px 1px 5px #111111
}

ul>li:fist-child{
	padding-top:50px
}

319 bytes

Nivel alto

html,body{width:100%;margin:0 auto}
h1,h2,h3,h4,h5,h6{font-size:18px;font-family:'arial'}
div span{display:block;color:#ffffff;text-align:center}
div+.background{background:#000000;-webkit-box-shadow:1px 1px 5px #111111}
ul>li:fist-child{padding-top:50px}

256 bytes

Nivel máximo

html,body{width:100%;margin:0 auto}h1,h2,h3,h4,h5,h6{font-size:18px;font-family:'arial'}div span{display:block;color:#fff;text-align:center}div+.background{background:#000;-webkit-box-shadow:1px 1px 5px #111}ul>li:fist-child{padding-top:50px}

242 bytes

NOTA: En archivos CSS de mayor tamaño la reducción es más notable.


Mejoras y sugerencias

En posteriores versiones se implementará la posibilidad de eliminar propiedades obsoletas de CSS, mejoras en la compresión de las propiedades (por ejemplo margin: 15px 10px 15px 10px se convertiría a margin: 15px 10px), descartar y eliminar propiedades inválidas, comprimir y convertir colores RGB a HEX…

Si quieres reportar algún fallo, colaborar en el proyecto o hacernos alguna sugerencia por favor ponte en contacto con nosotros a proyectos@securitynull.net


FUENTES

http://minify.googlecode.com
http://regexadvice.com