En un proyecto en el que estoy trabajando actualmente se requiere generar un XML con datos tratados, para que un código Javascript monte un grid a modo de Excel online.
El problema viene cuando la cantidad de registros se vuelve grande… En unas pruebas con registros de producción nos encontramos que el grid se demoraba mucho en mostrarse… Pusimos algunas alertas y llegamos a la conclusión que de 20 segundos que tardaba en montarse el grid, sólo 5 correspondían a la generación del XML y el resto era tráfico de red y proceso javascript.
Pero cuánto pesa el XML? Un mega y medio de XML? Y cómo lo hacemos más pequeño para generar menos tráfico y ganar tiempo? Comprimiendo el XML de salida…
¿De qué se trata?
Los datos que se encargan de montar una página web son básicamente imágenes y diferentes tipos de datos en texto plano. Las imágenes habitualmente ya vienen comprimidas (JPG, PNG, GIF,…), pero el texto plano (HTML, XML, CSS, …) es altamente comprimible… Simplemente es código ASCII que se repite y repite en el mismo archivo. Si enviamos el texto plano comprimido estamos enviando realmente menos datos por la red, consiguiendo que la totalidad de los datos llegue antes al navegador, quien descomprime los datos y obtiene el código HTML, XML, CSS o lo que sea como si se hubiese enviado así directamente.
¿Y los navegadors lo soportan?
Casi la totalidad de navegadores actuales soportan la compressión de datos HTTP. De hecho, desde 1998 los navegadores han ido soportando el protocolo HTTP 1.1, que esencialmente indica que el navegador soporta “content encoding”.
Internet Explorer soporta compresión HTTP desde la versión 4 (teniendo que activar HTTP 1.1 en sus propiedades) aunque las versiones para Mac 4.5/5 no lo soportan. Netscape lo soporta desde la versión 4 aunque da bastantes fallos. Su versión 4.5 empieza a ser más interesante y la 6 funciona ya plenamente. Opera soporta la compresión desde su versión 5. Firefox desde su versión 1.
Para asegurarte que tu navegador soporta compresión puedes usar el test HTTP trace. Si aparece una línea dentro del cuadro “HTTP request received from browser” con un texto similar al siguiente es que sí que lo soporta:
ACCEPT_ENCODING: gzip,deflate
¿Cómo implementarlo?
Se puede hacer de 3 formas:
- Activar a nivel TOTAL del ámbito del php del servidor (editar php.ini)
- Activar a nivel LOCAL para un sólo site de todo el ámbito del PHP (.htaccess)
- Activar a nivel de SCRIPT (un sólo archivo.php)
1.- TOTAL
- Editar el php.ini de apache
$ vim /etc/php5/apache2/php.ini
- Cambiar el valor de los parámetros siguientes:
zlib.output_compression = On
zlib.output_compression_level = 7
- Guardar y salir
- Reiniciar apache
$ /etc/init.d/apache2 restart
2.- LOCAL
- Editar o crear el archivo .htaccess en el directorio del sitio a aplicar
$ vim /var/www/misitio/.htaccess
- Insertar las siguientes líneas:
php_flag zlib.output_compression on
php_value zlib.output_compression_level 7
- Guardar y salir (no es necesario reiniciar)
3.- SCRIPT
Hay dos formas de hacerlo:
- Insertar al inicio del script la siguiente línea
ini_set(’zlib.output_compression’, ‘On’);
NOTA: Según el comentario en php.net esta forma no funciona.
Personalmente yo no lo he probado.
- Insertar al inicio del script la siguiente línea
ob_start(”ob_gzhandler”);
NOTA: Sin haber activado el zlib desde php.ini, al ejecutar ésta línea me causaba un error.
Niveles de compresión:
Van de 0 a 9 indicando de menos a más compresión respectivamente. A menos compresión más rápido es y menos CPU consume, pero menos comprime. A más compresión se tarda más en comprimir y consume más CPU, pero la compresión es mejor. Establecer el valor a -1 hace que se deje a elección del propio PHP el nivel de compresión (generalmente 6).
¿Cómo saber si está funcionando?
Se pueden usar herramientas de testeo como HTTP Analysis Tools. Para este caso, probar la primera herramienta “Compression Check“
Experiencia personal
En el proyecto que he descrito, el XML medio pesaba sobre 1,5 MB. Al comprimir la salida se queda en unos 35 KB, una muy buena mejora. La solución que tomé fué aplicar la compresión a todo el site setando los parámetros directamente en el php.ini. La generación del XML sigue tardando lo mismo pero el tiempo total para tener el XML listo en el navegador descendió de 25 segundos a unos 10 segundos… una muy buena mejora
Luego, quise hacer lo mismo en este blog. Como está alojado en un servidor compartido no tengo acceso al php.ini, así que probé de hacer el setado por .htaccess, pero obtuve siempre un error 500. La única forma de hacerlo funcionar fué editar el archivo index.php y colocar en la primera línea el ob_start(”ob_gzhandler”). La compresión funcionó y los registros mejoraron, pero la experiencia del usuario empeora debido a que el el navegador no renderiza hasta que no le han llegado todos los datos… y cómo hay algunos scripts de publicidad que se llaman y demoran todo el conjunto, la web se queda unos segundos (que se hacen eternos) en blanco. Así que lo quité dejándolo sin comprimir. Así, almenos, el usuario ve que se le va renderizando la web sobre la marcha y no tiene la sensación de que el sitio está colgado.
Más información:
Tags: Comunicación, Optimización, PHP, Programación, Server
Escribe un Comentario