Librairies JavaScript : Connaissez vos outils
mercredi 27 août 2008 - 3 commentaires
Certes je n'aime pas les librairies JavaScript en général. Beaucoup de code téléchargé, parsé, exécuté pour n'utiliser la plupart du temps qu'un ensemble très réduit de fonctionnalités. Mais bon, mettons ça de côté aujourd'hui car il faut l'admettre, elles rendent tout de même de bons services.
On va quand même garder un point qui m'embête : ces librairies cachent souvent la complexité du code qu'elles exécutent. Pour démontrer cela, mettons nous en situation ! L'exemple sur la page suivante contient 1729 paragraphes de deux mots. Pour une raison évidente[1], nous voulons cacher le deuxième mot de chaque paragraphe. Pour cela, nous utilisons jQuery de deux manières différentes.
La méthode toggle
$('span').toggle();
Que fait réellement cette simple ligne ? Elle va récupérer tous les éléments <span> de la page puis leur appliquer la méthode toggle. Pour chaque élément trouvé (1729 je rappelle), elle va vérifier s'il est affiché ou non et lui appliqué un style en conséquence. C'est tellement long que votre navigateur risque de bloquer sur la page de test.
La méthode classe
$('div').eq(0).toggleClass('hidden');
Jeu de mot pas terrible mais qui résume bien la situation. Ce code récupère tous les éléments <div> de la page et ne travaille que sur le premier. Sur ce <div>, elle va regarder s'il a la classe hidden et en fonction, lui ajoutera ou enlèvera cette classe. Voilà, c'est tout ce qu'elle fait. Ensuite, c'est le navigateur qui travaille comme un grand grâce à la règle .hidden span {display:none;}
. Évidemment, le moteur CSS de votre navigateur fera ça bien plus rapidement.
Conclusion
Évidemment, mon exemple avec autant d'éléments est grossier. Mais tout de même, la différence est fondamentale. Permettez-moi une analogie entre un accès DOM et un accès disque, c'est à dire les parties les plus lentes des deux algorithmes précédents. Dans le premier cas, un premier accès en lecture (récupérer tous les spans) puis 1729 accès en lecture (est-il affiché ?) et 1729 accès en écriture (réglons son affichage). Dans le deuxième cas, nous avons un premier accès en lecture (récupérons tous les divs) puis un accès en lecture (est-ce que la classe est présente ?) puis un accès en écriture (ajoutons ou enlevons la classe). Le calcul est vite fait...
De manière générale, rappelons qu'il faut le moins possible toucher au style d'un élément. Si vous devez accéder plus de deux fois à l'attribut style, il sera plus profitable de passer par une règle CSS. Le moteur CSS sera toujours plus rapide que vous. De plus, vous permettez aux intégrateurs de pouvoir styler votre page en ne changeant que quelques classes. Et votre code d'affichage reste cantonné aux fichiers CSS, merci la maintenabilité.
Note
[1] parce qu'il faut bien un exemple à la con
Commentaires
Je ne comprend pas ce que tu cherches à montrer. Tu commences en disant que les framework JS c'est le mal, et ensuite tu compares deux fonctions d'un même framework. Je m'attendais à ce que tu compare du code natif et la même fonctionnalité via un code framework.
En fait ce n'est qu'après relecture que je comprend que le point que tu veux souligner, c'est le choix de la fonction framework. Oui, le choix est important. Ca me semble couler de source, mais on peut toujours le rappeler.
Concernant ta conclusion, ton "de plus" est une raison totalement suffisante en soi. Il ne faudrait pas que le fichier JavaScript contienne plus de CSS que le fichier CSS lui-même. Aussi, une bonne pratique est d'utiliser exclusivement des classes dans le JS, à l'exception des éléments de style qui servent uniquement un mécanisme de l'interaction javascript.
Mootools va dans ce sens — dans le bon sens — avec son objet Morph qui permet de passer d'une classe CSS à une autre, en animant toutes les propriétés qui varient.
Un des points du discours d'Anthony est probablement à propos des horreurs qu'on voit fleurir. Les framework CSS ajoutent des abstractions et trop de gens les utilisent sans comprendre ce que ça fait derrière, ou sans en prendre compte.
Le résultat c'est que ce qui est fait via ces framework peut parfois prendre 10 ou même 10000x plus de temps. Pas forcément à cause du framework lui même, mais plus de sa mauvaise utilisation et du principe même de passer par une abstraction pour quelque chose qui devrait être simple si c'était bien fait.
Le second est assez classique : ne touchez pas la présentation en javascript, jamais. C'est pénible autant pour la maintenance, que pour le développement ou pour les performances.
Et que penses-tu de $($('div')[0]).toggle() ?