28172 sujets

CSS et mise en forme, CSS3

Bonjour,

Est-ce que les sélecteurs utilisés peuvent avoir un impact sur les performances.

Par exemple, si j'ai le code suivant:

<div id="elem1" class="myClass"></div>
<div id="elem2" class="myClass"></div>


Est-il plus performant d'utiliser le sélecteur #elem1,#elem2 plutôt que .myClass ?

Merci
Modifié par Mathieu_vd (18 Jul 2008 - 11:38)
Bonjour.

À mon avis personne n'a fait de tests à ce sujet et même si l'un des deux était vraiment plus performant que l'autre on ne pourrait s'en passer de toute façon puisque les classes et les ids ont tous deux des rôles distincts.
Bonjour Chancago,

Mon exemple (très simple) n'est qu'un moyen d'illustrer ma question.
J'aurais pu en donner pleins d'autres plus extrême comme l'usage du * dans le sélecteur.
Ou encore, j'aurais pu écrire: Y a-t-il une différence au niveau performance si j'utilise #elem1 ou div[id="elem1"] ?

Il ne faut donc pas croire que ma question se résume en fait à "Vaut-il mieux utiliser un id ou une classe ?"

Pour en revenir à la question initial, une piste de réponse serait de savoir comment le navigateur match le sélecteur avec les éléments. Parcourt-il le DOM d'une manière comparable à ce que fait JS ?
Modifié par Mathieu_vd (17 Jul 2008 - 13:25)
Salut,

J'ai pas de réponses non plus mais la question m'intéresse aussi!

Effectivement plus que de comparer les classes et les id c'est plus pour savoir si c'est mieux d'écrire (pour comparer au js):

#menu li.item{} que .item{}
A ben oui très bon exemple matmat ! Smiley cligne

J'avais du mal à en trouver un vraiment pertinent et maintennat cela me parait évident.

Et je suis heureux de ne pas être le seul à me poser la question Smiley biggrin

Merci
Modifié par Mathieu_vd (17 Jul 2008 - 16:09)
matmat a écrit :
Salut,

J'ai pas de réponses non plus mais la question m'intéresse aussi!

Effectivement plus que de comparer les classes et les id c'est plus pour savoir si c'est mieux d'écrire (pour comparer au js):

#menu li.item{} que .item{}
C'est évident que le premier est plus long car il y a deux conditions au lieu d'une pour le deuxième ...

Édit : j'ai parcouru rapidement les pages citées ci-dessus et j'ai toujours la même réflexion : ce n'est pas aux développeurs de sites web de s'occuper de performances aussi minimes, c'est aux développeurs de navigateur qu'il advient d'optimiser la lecture des CSS. À mon avis la priorité pour les développeurs de site web c'est de produire du code lisible, d'utiliser la bonne technologie pour la bonne tâche, etc.
Modifié par Changaco (17 Jul 2008 - 17:31)
Changaco a écrit :
À mon avis la priorité pour les développeurs de site web c'est de produire du code lisible, d'utiliser la bonne technologie pour la bonne tâche, etc.


D'accord avec toi mais cela ne l'empêche pas d'être curieux Smiley cligne

Changaco a écrit :
C'est évident que le premier est plus long car il y a deux conditions au lieu d'une pour le deuxième ...


Par forcément. Il pourrait être plus rapide d'accèder à un élement via son id unique et de le parcourir pour trouver les éléments qui correspondent à une classe donnée. Si on ne donne que le nom de la classe, on pourrait devoir parcourir tout le dom.

En js, si on admet que les éléments <li> sont uniquement présent dans l'élément #elem1, il sera plus rapide de faire
document.getElementById('elem1').getElementByTagName('li')


plutôt que
document.getElementByTagName('li')


Dans le deuxième cas, il faudrait parcourir l'ensemble du DOM alors que dans le premier on ne fera que parcourir #elem1
Modifié par Mathieu_vd (17 Jul 2008 - 17:56)
Mathieu_vd a écrit :

En js, si on admet que les éléments <li> sont uniquement présent dans l'élément #elem1, il sera plus rapide de faire
document.getElementById('elem1').getElementByTagName('li')


plutôt que
document.getElementByTagName('li')


Dans le deuxième cas, il faudrait parcourir l'ensemble du DOM alors que dans le premier on ne fera que parcourir #elem1


De la même manière pour un classe seule (.class) en js il faut faire une boucle sur toutes les balises de la page avec une RegExp.

Donc si on assigne un contexte on réduit considérablement le nombre de boucle et si on détermine le nom de la balise on évite le "*" et réduit encore le nombre de boucles.

Maintenant ce n'est pas sûr que cela soit vrai pour le selecteur css, en effet si on reprend l'exemple du js, on s'aperçoit que les navigateurs qui implémentent le getElementsByClassName en natif n'ont pas de problème de performance sur cette fonction (voir ces tests http://ejohn.org/blog/getelementsbyclassname-speed-comparison/ intéressant, la fonction native et 100 fois plus rapide!).
A la lecture des documents linkés par 20cent, cela semble plutôt le contraire parceque le fonctionnement du selecteur css est différent d'un selecteur js, en effet il construit d'abord un index des id et des classes donc:

#id : le plus rapide
.class : pas loin derrière
div#id : inutile!
div.class : moins rapide (mais peu être utile)
#menu li ou .menu li moins rapide que .menu-item (dommage!)

En conclusion, Changaco avait raison, moins il y a de règle plus c'est rapide.

Par contre apparemment, la différence est vraiment subtile, donc il faut vraiment avoir de gros document pour que tout cela soit valable.

Il y a tout de même un petit quelque chose a retenir pour un menu par exemple qui a un identifiant #menu il vaut mieux :

#menu{font:size:24px}
que
#menu li{font:size:24px}

si, bien sûr, les deux ont le même effet recherché, sinon il vaut mieux mettre en priorité la lisibilité du code html et sa facilité de maintenance que d'essayer d'optimiser les performances des feuilles de styles, les gains sont trop dérisoires.
Modifié par matmat (17 Jul 2008 - 18:50)
matmat a écrit :
...sinon il vaut mieux mettre en priorité la lisibilité du code html et sa facilité de maintenance que d'essayer d'optimiser les performances des feuilles de styles, les gains sont trop dérisoires.


Surtout que rien ne nous dit que les autres navigateurs que Firefox fonctionnent exactement de la même façon...

Merci pour vos interventions.

J'attends un peu avant de placer le sujet en résolu car quelqu'un pourrait encore apporter un complément d'information.
Modifié par Mathieu_vd (17 Jul 2008 - 21:46)
Juste par curiosité la question m'interessait aussi, même si j'avoue n'avoir jamais eu à me préocupper d'optimisation à ce niveau là.

Il me semble plus judicieux d'optimiser le poids de sa feuille de style et de son fichier html plutot que de jouer sur la vitesse d'interprétation des règles appliquées, par exemple en utilisant les notations courtes dans le css, et en évitant au maximum les classes inutiles dans le css (<li class="menu-item">...</li> x 10) ou en compressant (cssTidy) les feuilles de styles terminées.

Mais bon, là je ne pense pas apporter grand chose au débat Smiley smile
J'imagine qu'aucun d'entre nous n'a jamais été confronté à devoir optimiser ses pages jusqu'à ce niveau de détail.
Tymlis a écrit :
J'imagine qu'aucun d'entre nous n'a jamais été confronté à devoir optimiser ses pages jusqu'à ce niveau de détail.
En effet les questions d'optimisation de cet ordre servent en général à définir des conventions de codage comme le guillemet simple vs guillemet double et PHP.
Tymlis a écrit :
J'imagine qu'aucun d'entre nous n'a jamais été confronté à devoir optimiser ses pages jusqu'à ce niveau de détail.

Le blog d'Éric prouve un peu le contraire quand même. Smiley cligne
Pour répondre en vrac :

- Oui c'est au navigateur de s'occuper des optimisations et des gains de performance. Par contre vu qu'ils ne sont pas parfaits et parce que tout n'est pas toujours équivalent, c'est au développeur web de savoir comment fonctionne l'outil pour ne pas faire n'importe quoi.

Si je devais faire un parallèle avec le SQL : les SGBDR sont très bon pour optimiser les chemins des requêtes, mais il reste qu'en choisissant une méthode ou une autre, on peut multiplier par 10 les temps de calcul.

Maintenant oui, la clarté du code, la maintenance, la lisibilité ... tout ça est très important aussi donc si les gains de perf sont négligeables c'est ce qui doit primer.



- Les gains de performance (ou pertes, suivant) sont effectivement minimes. Maintenant pour le savoir il faut faire des tests ou étudier la question. Donc autant la réponse peut être "passez votre chemin", autant la question elle est tout à fait pertinente (ou en tout cas j'ai eu la même Smiley cligne ) et intéressante à poser.

Par contre savoir comment fonctionne le moteur derrière est important. Ben oui, même si on dit que c'est au navigateur d'optimiser les performances, le développeur est humain et il aura tendance à toujours intuitivement faire des choses "pour aider" même s'il dit se désintéresser des perf. Sauf que si on ne sait pas comment ça fonctionne .... on peut faire l'inverse.

L'idée là ce que avec la doc on sait que les CSS s'interprêtent de droite à gauche. Vos exemples de parcours DOM s'interprêtent eux de gauche à droite. Bref, les conclusions et les techniques à adopter pour aider les performances peuvent être tout à fait opposées sur certains points. On sait aussi que le navigateur créé un index sur les noms de balise, sur les classes et sur les identifiants (mais pas sur les attributs quelconques). Donc accéder à une classe est rapide même sans préciser le nom de balise (alors qu'en js, à défaut de getElementsByClassName c'est l'opposé)


- Pitié ne parlez pas de performance pour les questions de guillemet / apostrophe dans PHP. La différence est négligeable par rapport aux aléas de mesure, même sur les très gros scripts. Et quand vous avez un optimisateur type Zend ou APC derrière, le gain est virtuellement nul.
Edas a écrit :
L'idée là ce que avec la doc on sait que les CSS s'interprètent de droite à gauche. Vos exemples de parcours DOM s'interprètent eux de gauche à droite. Bref, les conclusions et les techniques à adopter pour aider les performances peuvent être tout à fait opposées sur certains points. On sait aussi que le navigateur créé un index sur les noms de balise, sur les classes et sur les identifiants (mais pas sur les attributs quelconques). Donc accéder à une classe est rapide même sans préciser le nom de balise (alors qu'en js, à défaut de getElementsByClassName c'est l'opposé)
Sauf que là on connaît uniquement le fonctionnement de Gecko et pas le fonctionnement des moteurs d'IE, Opera, WebKit ... Donc même si on sait que pour Gecko moins il y a de règles mieux c'est on ne sait pas si ça ne ralenti pas les autres navigateurs ...