Durante los últimos meses me he incorporado a una nueva compañía en la que trabajo sobre Ruby on Rails. Esto me ha descubierto un universo nuevo, al igual que cuando empecé a trabajar sobre Magento. Rails tiene muchísimas funcionalidades y es un framework muy potente con muchas características que están orientadas a hacer el desarrollo más fácil. Una de ellas es Turbolinks.

¿Qué es Turbolinks?

Turbolinks es un módulo orientado a aumentar la velocidad de carga de una web modificando el comportamiento de los enlaces internos. Digamos que lo que hace es reemplazar, tras una llamada ajax el contenido del body del documento dejando intacto el head del mismo. Bueno, intacto no. Modifica también la etiqueta <title>. Además, utiliza la API de html5 para modificar el historial del navegador, de forma que se hace similar a una navegación web natural, con los mismos efectos, pero ahorrando peticiones HTTP al servidor, ya que no se piden ni los JS ni los CSS que se incluyen en la cabecera.

Suena bien, ¿eh? Al menos como concepto. Aunque no es oro todo lo que reluce… Trabajando con esta herramienta me he encontrado con varios problemas… Intentaré explicarlo con detalles y cómo traté de solucionarlo (en el caso de que haya podido).

¿Qué sucede con el estado ‘ready’ del documento si uso jQuery?

No nos engañemos. Muchos usamos jQuery como base de nuestro trabajo, y cuando usamos jQuery tendemos a utilizar estructuras como la siguiente.

jQuery(document).ready(function(){
    /* Aquí va tu acción */
});

Pero cuando usas Turbolinks, al no actualizarse el documento como tal, este evento no tendrá efecto porque en el navegador el documento sigue siendo el mismo. Pero… ¿Cómo podemos salvar este problema? Bien, la propia herramienta nos provee con un evento que sí que podemos escuchar. Según la versión de Turbolinks que estemos utilizando, este evento puede ser turbolinks:loadpage:load dependiendo de la versión de turbolinks que estemos utilizando. De tal forma que en Turbolinks 4 en lugar de la estructura anteriormente mencionada deberíamos utilizar esta:

jQuery(documet).on('page:load', function(){
    /* Aquí va tu acción */
});

Y si utilizamos Turbolinks 5 sería así

jQuery(documet).on('turbolinks:load', function(){
    /* Aquí va tu acción */
});

Este evento se ejecuta tanto en la primera carga del documento, simulando el ready, y cada vez que Turbolinks actualiza el contenido de la web. Con esto ya tenemos solucionado el problema del “document ready”.

¿Y si quisiera añadir mis scrips dentro del body?

En ese aspecto la cosa se complica… Aun no he dado con la solución a esto, pero os voy a contar mi problema al respecto. Lo más común es poner los scripts importantes y las librerías de las que dependen otros script en la cabecera (<head>) del documento. Aunque, si atendemos a WPO, lo lógico es colocarlos al final del documento, justo antes del cierre del head. Y aquí viene el problema. Turbolinks actualiza el body. Todo él, (no he dado con la forma de) no hay forma de declarar “secciones” que sean “inmutables” o que no se “recarguen” los script. Así que si en dos páginas distintas tienes, digamos, un script que añade contenido al sidebar cuando haces click en un botón y has accedido a ambas navegando a través de Turbolinks, habrás cargado ese script dos veces en el navegador, se ejecutará dos veces cuando hagas click y, por tanto, ese contenido se colocará en el sidebar dos veces. Esto me ha dado muchos quebraderos de cabeza… Lo único que se me ocurrió cuando me surgió este problema es devolver esos scrips que necesitaba al head. Cosa que no me hace especial ilusión, pero mientras tanto seguiré investigando cómo solucionarlo.

Bola Extra

Este asunto que voy a tratar ahora es una pregunta que se me vino a la cabeza hace poco, no va tan orientado al desarrollo, pero quizá haya alguien a quien le pueda servir.

¿Si Turbolinks solo “añade” los scripts diferentes y actualiza la etiqueta <title>, no se verá mi SEO comprometido?

La respuesta a esto es NO. Los motores de búsqueda como Google hacen peticiones distintas a las que puede hacer un navegador, son independientes del comportamiento de Turbolinks e informaciones como la metadescripción o cualquier otra metaetiqueta serán actualizadas, siendo registradas y leídas por el indexador en cuestión correctamente.

Conclusión

Turbolinks es una heramienta que agiliza el tiempo de carga de tu web y las peticiones que hace, quizá con la llegada de HTTP/2 no sea necesario, pero hasta que se estandarice puede ser un gran aliado. Sin embargo, si tienes una web con una gran dependencia de JavaScript, esta herramienta da más dolores de cabeza de los que soluciona, así que no te recomiendo usarla en esos casos.

Si has tenido una experiencia diferente usando Turbolinks o crees que los problemas que cito tienen solución, no dejes de compartirla en los comentarios.