Tutoriel Vidéo JavaScript Turbolinks

Télécharger la vidéo

Je vous propose aujourd'hui de découvrir la librairie JavaScript Turbolinks. Comme son nom l'indique le principe de cette librairie JavaScript est de booster le temps d'affichage des liens internes en utilisant un système de chargement Ajax.

Comment ça marche ?

Présenté comme ça on peut penser que Turbolinks est une librairie un peu magique mais le principe est en fait relativement simple :

  • Lorsque l'on clique sur un lien interne, la page suivante va être chargée en Ajax.
  • Le contenu de la page en cours (le DOM) est mis en mémoire (pour un affichage ultérieur plus rapide).
  • Le contenu (<body>) de le page suivante est injecté dans la page en cours et remplace le contenu précédent.
  • Un évènement turbolinks:load est généré sur le document pour remettre en place les différents comportements JavaScript.

Les avantages ?

Cette méthode de chargement permet de donner l'impression à l'utilisateur que le site charge plus rapidement en évitant l'affichage d'une page blanche pendant le chargement de la page suivante. Il permet aussi au navigateur de ne pas avoir à réinterpréter le JavaScript et CSS pour chacune des pages. La mise en mémoire des pages permet aussi un affichage plus rapide des pages déjà visitées.

Un autre avantage indirect est que l'utilisateur ne "recharge" jamais vraiment votre site, ce qui permet de persister une connexion en websocket pendant la navigation et ainsi mettre en place des systèmes plus complexes (comme un système de notifications en temps réel ou un tchat).

Les inconvénients ?

Cette méthode a un impact assez conséquent sur votre JavaScript. Vu que chaque page est chargée en Ajax il faut "rebind" tous vos évènements à chaque chargement. Pour cela en plus de greffer les évènements au chargement de la page il faudra aussi utiliser 'turbolinks:load', ce qui peut s'avérer relativement complexe avec des librairie tiers.

document.addEventListener("turbolinks:load", function() {
  // ...
})

L'autre souci est que cette évènement est déclenché à chaque injection de contenu dans la page, même si la page est rechargée depuis le cache. Le problème est alors que le DOM réinjecté possède déjà les évènements en question. Il faut donc que votre code JavaScript soit "idempotent", même si il est appliqué plusieurs fois sur la page il ne doit pas reproduire les changements aux éléments déjà traité.

Si par exemple vous faite un

document.addEventListener("turbolinks:load", function() {
  document.querySelector('#demo').addEventListener('click', function () {
    console.log('Clic')
  })
})

L'évènement pourrait se retrouver greffé plusieurs fois et entrainer des problèmes plus ou moins importants sur votre application. Pour remédier à ce souci, vous pouvez ajouter un attribut afin d'identifier les éléments déjà traités.