Turbolinks es una herramienta que ha estado en Ruby on Rails desde la versión 4, en mis palabras es una librería de javaScript para acelerar tu aplicación; en palabras del repositorio en GIthub, Turbolinks hace que dirigirse a un link en tu aplicación web sea más rápido. En lugar de dejar que el navegador recompile el CSS y javaScript de tu sitio en cada cambio de página, Turbolinks mantiene la página actual funcionando y reemplaza solo las partes del cuerpo de la página necesarias.
Básicamente, cuando tienes Turbolinks en tu aplicación, al darle click a un link, la librería intercepta la petición, y la convierte en AJAX, de manera asíncrona solicita al servidor las partes a actualizar de tu sitio web, y sustituye lo que sea necesario.
Turbolink solo actualiza los tags body y el tag title del encabezado, de modo que no solicita de nuevo los assets de tu sitio, haciendo que la transición entre páginas sea más rápida (porque no cargas esos assets), además, como el repositorio lo menciona, evita que el navegador tenga que recompilar las hojas de estilos y los scripts de javaScript.
La intención de la librería es darte las ventajas de una SPA(Single Page Application), sin la complejidad de construir una, recordemos que una SPA (que puedes construir con Angular, Backbone, etc), significa que tienes que mantener dos partes de la plataforma, la lógica del servidor (que solo sirve datos) y la funcionalidad del sitio en javaScript; Turbolinks busca darte los mismos beneficios sin que tengas que mantener dos partes.
Integrar Turbolinks es transparente para tu aplicación, es decir, una app de Ruby on Rails con Turbolinks y sin Turbolinks se programa igual, las vistas son iguales, los controladores son iguales, todo es igual... excepto por los eventos en el navegador (más de esto a continuación), haciendo el proceso transparente, Turbolinks se asegura de que no tengas que adaptar tu plataforma web para darle el feeling de una SPA.
La plataforma de CódigoFacilito, como habrás notado, muestra un mensaje de "Cargando..." cada vez que clickeas un link, si recargáramos toda la página en cada link, sería imposible mostrarte el mensaje de que la página se está cargando, sin embargo, como estamos usando Turbolinks, sin hacer cambios podemos ofrecer ese pequeño UX (además del incremento en la velocidad al moverte entre links). Esto es lo único que agregamos para mostrar el mensaje de precargado:
$(document).on "page:fetch", ->
$(".loading-alert").fadeIn()
$(document).on "page:change", ->
$(".loading-alert").fadeOut()
Además de claro añadir el div que contiene el precargado:
.loading-alert.white-text.blue.large-padding.text-center.z-depth-3
%i.mdi-action-cached.spin
Cargando...
.absolute.full-width
.progress#progress{style:"margin-top:0px;z-index:999;display:none;"}
.indeterminate.red
Y listo... Turbolinks for the win.
Los problemas de Turbolinks
El principal problema de TurboLinks, es que la ejecución del código de javaScript es persistente entre peticiones, es decir, cuando cambias de link, el código sigue como estaba, las variables declaradas siguen como están, los intervalos creados siguen ejecutándose, es decir, todo continúa.
Plus, la página nunca recarga, solo cambia las partes necesarias... ¿eso es problema? Lo es para tus eventos. Es común que todo lo que necesitemos ejecutar al inicializar la página lo coloquemos en la ejecución del evento "load" de la página:
window.addEventListener("load",function(){
// Aquí la inicialización porque nos aseguramos de que el sitio ya ha cargado
});
Alternativamente podemos poner el script al final de la página para obtener el mismo resultado... ¿el problema? El problema es que el navegador no vuelve a disparar el evento load no importa que hayas cambiado la página, porque pues no la ha recargado. Eso significa que tu script está roto. La pregunta es ¿cómo ejecuto código cada que cambio la página?
Par de alternativas, primero, podemos utilizar la gema de kossnocorp, jquery.turbolinks, esta es mi recomendación para solucionar posibles problemas con el binding de eventos de librerías o frameworks externos, si por ejemplo estás usando Bootstrap, Materialize o similares, no dudes en agregar la gema a tu Gemfile:
gem 'jquery-turbolinks'
E instalarla
bundle install
Segunda recomendación, utiliza los eventos que TurboLinks dispara cuando recarga el sitio junto con los que normalmente usas. Un ejemplo de esto es el precargado, nota como esperamos al evento page:fetch (hicieron click en un link y TurboLinks fue por la página) y page:change (se cargó una página nueva con TurboLinks), en otras palabras esto:
$(document).ready ()->
# Aquí ya cargó el sitio en aplicaciones tradicionales
Se convierte en esto:
$(document).on "ready page:load page:restore", ()->
# Se dispara la primera vez que carga la página, al cambiar de sitio y cuando regresas a una página anterior
Problemas resueltos.
TurboLinks 5 y Aplicaciones híbridas
Hace poco más de un mes, DHH anunciaba en twitter que TurboLinks 5 estaba en fase beta y podíamos iniciar a usarlo:
Turbolinks 5.0.0.beta1: https://t.co/KmPRS8Nxkb – rewritten from ground up, native mobile app wrapper integration, powers Basecamp 3 apps!
— DHH (@dhh) 4 de febrero de 2016
TurboLinks 5 es una idea que en lo personal me parece revolucionara, tanto como para DHH quien cree que es como cuando liberó Ruby on Rails:
Looking back at the body of work, that level of productivity w/ Turbolinks + Majestic Monolith, it feels like a 2004 “secret weapon” again.
— DHH (@dhh) 19 de febrero de 2016
That same sensation as when Rails was released that we were doing something substantially different from the norm to get outsized results.
— DHH (@dhh) 19 de febrero de 2016
¿Qué hay de especial en TurboLinks 5? TurboLinks se me hizo siempre una idea interesante, me gustan las SPA's, me gusta que la página no recargue, me gusta ese dinamismo... pero desarrollar Angular, Backbone, etc. no se sentía ágil para mí, desarrollar dos veces una lógica muy similar, debugear una SPA no es tan transparente como una aplicación web tradicional... TurboLinks quitó esos dolores y trajo un feeling similar, bien... pero ahora es mucho más que eso.
Apps híbridas
¿Recuerdan que TurboLinks solicita una parte de tu sitio y nada más? ¿Recuerdan que trae del servidor solo la parte importante que necesita? Qué pasaría si esa parte importante la colocamos en un WebView e instanciamos uno por cada Link.... eso ya lo hicieron:
TurboLinks 5 vino acompañado de un SDK para Android y para iOs, además, usando Electron y TurboLinks 5, el equipo de Basecamp construyó aplicaciones para Mac y Windows.
Las aplicaciones móviles que se acompañan de TurboLinks "son nativas" en el sentido de que necesitas abrir AndroidStudio o xCode, necesitas integrar el SDK y definir qué hará TurboLinks cuando alguien clickee un link. Además claro puedes responder a notificaciones, enviarlas y más... por todo lo demás, es HTML, CSS y JS. Es como Phonegap pero sin tener las vistas (HTML) en el proyecto de la app, las vistas se mandan desde el servidor, no están en el dispositivo.
El SDK te permite definir si abrirás un nuevo Intent (hablando en palabras Android), si solo instanciaras un nuevo WebView o qué pasará cuando un usuario trata de moverse en tu app. Así que básicamente:
Responsive + Turbolinks = App híbrida lista. pic.twitter.com/2I43Klbmrp
— Uriel Hdz (@Uriel_Hedz) 10 de marzo de 2016
¿Quieres saber más?
Te recomiendo ampliamente el curso de Backend 2016, vamos a crear una red social con Ruby on Rails, vamos a ver varias cosas de TurboLinks y para otro curso quisiera crear apps para la red social utilizando lo que aquí te conté. ¿Suena muy interesante no? Es genial... Rails es perfecto para las startups porque te permite hacer esta clase de cosas, ser súper productivo con equipos pequeños de trabajo, hoy puedes tener apps "nativas" para Mac, Windows, iOs, Android y crear una sola base de código en Ruby on Rails.
PD: Rails 5 tiene otras cosas muy interesantes además de TurboLinks, tiene ActionCable para crear aplicaciones en tiempo real y también lo enseñaremos en el curso de Backend 2016.