Algunas veces no nos paramos a pensar en los cambios que añade una web, en este caso Google, los problemas que pueden aparecer en tema de rendimiento. Y estos problemas suelen ser fundamentales a la hora de la impresión que se lleva un usuario de la web, claro, que Google no se caracteriza por problemas de rendimiento y los expertos que están trabajando allá deben ser de lo mejorcito que existe.
Después de este rollo introductorio, me gustaría apuntar los 3 aspectos que utiliza Google para mejorar el rendimiento que se centran sobre todo en la reducción del número de peticiones HTTP:
Compilación de Javascript: mediante Closure Compiler, consigue reducir el tamaño de los ficheros js, reutilizar variables, …
JSONP bajo demando: JSONP permite envolver la respuesta JSON con una llamada Javascript. Se realizan llamadas directas al script en vez de usar Ajax, lo cual permite hacer llamadas crossdomain y que el navegador lo cachee perfectamente. El problema es que si se añade la llamada con un createElement, el navegador se queda cargando, por lo que es mejor meterlo entre un setTimeout.
DATA URIs: es un método de añadir contenido en URLs usando base64, el problema es que IE8 sólo admite DATA URIs de 32k, por lo que dividen las imagenes en trozos y los “empalman” con etiquetas IMG. También han comprobado que aunque base64 añade hasta un 33% del tamaño, como lo devuelven en gzip, el tamaño final es más o menos el mismo.
Más consejos que siempre viene bien, algunos los conoceremos, otros simplemente los usaremos de forma automática y otros serán nuevos para nosotros. En este caso se trata de consejos para depurar nuestras aplicaciones.
Comprueba los datos: comprueba que los datos son los que se esperan. Una buena opción serÃa darle la funcionalidad al sistema de exportar los datos a un fichero de texto plano para poder comprobarlo mejor.
Comprende el sistema: leer el manual, seguir las instrucciones, compara tu código con los ejemplos que ofrecen, puede ayudarte a usar el sistema correctamente y no mandar datos que no son los correctos.
Hazlo fallar: para encontrar posibles fallos no hay nada mejor que hacerlo fallar a proposito. Si algo falla rara vez, puede ser algo bastante importante, no asumas cosas cuando intentes encontrar el problema, te puede hacer perder mucho tiempo.
Tómate tu tiempo: sacar conclusiones usando poca información nos puede hacer no encontrar el problema real, sino parchear un problema menor.
Divide y conquistarás: estrecha tu búsqueda, limita los sitios donde pueda darse el error, sigue el código hasta la zona más exacta donde pueda fallar.
Realiza una auditorÃa: da igual que parezca que todo funciona bien, sigue mirando los logs por posibles errores, por si aparecen casos que no habÃas visto antes.
Comprueba primero lo obvio: no asumas que tus ideas son correctas, cuestionate todo.
Pide ayuda: los test de caja negra dicen que quien debe testear la aplicación no debe ser quien la ha desarrollado, ya que muchas veces caemos en el error de pensar que algo en particular no va a fallar porque sabemos cómo funciona.
Si no lo corregiste, no está solucionado: las cosas no se arreglan solas, si no se reproduce de nuevo el error no quiere decir nada, el error sigue estando allÃ.
Aunque no soy muy fan de la moda del cloud computing, quizás porque se habla de ello muchas veces un tanto a la ligera, si que creo que desarrollar aplicaciones en arquitecturas basadas en la nube es algo que en el futuro tendremos que realizar (más basado en hosting que en servicios). Por ello estos consejos pueden ser interesantes:
Las máquinas son igualmente inseguros: es por ello que tampoco merece la pena gastar más medios en máquinas más críticas como la BD. Toda máquina falla, por lo que es mejor diseñar la arquitectura teniendo esto en mente para poder recuperarnos de una caída más facilmente.
Una aplicación en la nube depende absolutamente de la red y el IO, por lo que no es buena idea tenerlos “físicamente” muy lejos. Esto es uno de los motivos por los que yo, personalmente, no creo que tenga mucho éxito el concepto nube pensado como aplicación en Google y BD en Amazon (o parecido), algo que muchos se dedican a “vendernos”.
La red no es fiable, por lo que es conveniente tener sistemas de monitorización para saber qué ocurre en las máquinas y si tienen accesos unas a otras
El post original explica mejor cada punto y ofrece otros consejos más, que recomiendo leer.
La jerarquía de las plantillas de wordpress permite definir diferentes plantillas para mostrar según el tipo de contenido. Por ejemplo, la template para mostrar el contenido de un post es single.php, pero si es un custom post type podemos crearnos la template single-miposttype.php y que use esa plantilla específica para mostrar los contenidos del custom post type. Si se trata de una página mostrará page.php, y así con todos los tipos de contenido.
Lo que nos encontramos en ocasiones es que queremos ejecutar un javascript específico asociado a esa plantilla, lo cual podemos hacerlo a la hora de añadir los scripts preguntando por el tipo de contenido. Pero si lo queremos hacer de una forma más automática, podemos añadir en el filtro template_include la acción de añadir el script.
add_filter('template_include', 'js_load_script_template');
function js_load_script_template($template) {
// Obtenemos el fichero de la template que se usa
$js = pathinfo($template);
$js = $js['filename'];
// Me gusta obtener la versión del theme para evitar caches
$my_theme = wp_get_theme();
$version = $my_theme->get( 'Version' );
// Si el fichero js existe, p.e. single-miposttype.js lo añadimos
if (file_exists(get_template_directory().'/js/'.$js.'.js')) {
wp_enqueue_script( $js, get_bloginfo('template_directory').'/js/'.$js.'.js', array(), $version );
}
// Tambien ejecuto el script relacionado con la plantilla generica, p.e. single.js
$js_part = preg_replace('#^([^\-]+)\-.*$#', '$1', $js);
if ($js != $js_part && file_exists(get_template_directory().'/js/'.$js_part.'.js')) {
wp_enqueue_script( $js_part, get_bloginfo('template_directory').'/js/'.$js_part.'.js', array(), $version );
}
return $template;
}
En algunas ocasiones es necesario añadir contenido al calendario que te ofrecer el datepicker de jQuery UI, por ejemplo añadir un combo que indice “horario mañanas/tarde”. Para conseguirlo será necesario ‘toquetear’ un poco el objeto jQuery.datepicker.
Tendremos que hacer dos cosas: primero deberemos evitar que cuando se selecciona un día se cierre automáticamente el popup con el calendario y después tendremos que modificar el HTML que devuelve la clase.
Para evitar el auto-cierre tenemos que añadir la opción showButtonPanel ya que nos ofrecerá el botón “Close” que nos permitirá cerrar el popup cuando hayamos indicado todos los campos necesarios. También es necesario modificar la función jQuery.datepicker._selectDate tal y como lo indican en StackOverflow:
// Añadimos datepicker al input que queremos
jQuery('.fecha')
.datepicker({
showButtonPanel: true,
dateFormat: "DD, d MM, yy"
});
// Modificamos la funcion _selectDate
jQuery.datepicker._selectDateOverload = jQuery.datepicker._selectDate;
jQuery.datepicker._selectDate = function(id, dateStr) {
var target = jQuery(id);
var inst = this._getInst(target[0]);
inst.inline = true;
jQuery.datepicker._selectDateOverload(id, dateStr);
inst.inline = false;
this._updateDatepicker(inst);
// Usar el .html() para luego usar el .text() es porque si usas el regional de datepicker, te salen entidades html en vez de letras acentuadas
// Se le añade el valor del nuevo campo select que hemos incluido
target.val(jQuery('').html(dateStr).text()+' @ '+jQuery('#horario').val());
}
Bien, ya tenemos el evento onSelect modificado, ahora nos falta cambiar el HTML que se dibuja, para ello modificaremos la función jQuery.datepicker._generateHTML:
jQuery.datepicker._generateHTMLExtended = jQuery.datepicker._generateHTML;
jQuery.datepicker._generateHTML = function(inst) {
var html = jQuery.datepicker._generateHTMLExtended(inst);
var div = jQuery('').html(html);
div.find('table:first').after('
Horario:
');
return div.html();
}
// Incluimos tambien un evento para que cuando se seleccione el horario, se modifique el campo input
jQuery('#horario').live('change', function() {
var $obj = jQuery('.fecha');
$obj.val($obj.val().replace(/@.*/, '@ '+jQuery(this).val()));
});
estas recomendaciones no sólo sirven para jQuery, sino que para todas las librerÃas/frameworks.
faltó una: usar if en vez de switch/case.
y por qué usar if en vez de switch/case? cuesta mucho explicar para los que no saben?