Pour répondre a ce probleme, j'ai pris 4 approches différentes. On considere pour la démonstration que nos élements n'ont qu'une seule class (ce qui n'est pas forcement le cas en pratique), et que on doit commencer a chercher des la racine du document, pas apres. On ne prend pas non plus en compte les différences en terme d'occupation mémoire, ca sera pour un autre article.
Note: tous ces examples ont été testés uniquement avec Firefox. Ils devraient marcher avec des modifications mineures dans tous les autres navigateurs, a l'exception d'IE.sci
getElementsByTagName()
C'est la méthode la plus naive. On fait un getElementsByTagName('div'), et on
regarde l'attribut .className de chaque résultat pour oui ou non l'ajouter dans
un tableau final. Le code:
function getComments()
{
var a = document.getElementsByTagName('div');
var len = a.length;
var out = new Array();
for (var i = 0; i < len; i++)
{
if (a[i].hasAttribute('class') && a[i].className == "comment")
out.push(a[i]);
}
return out;
}
Parseur maison
Code écrit a l'origine par Daniel Glazman un jour ou j'avais donné la méthode
naive a quelqu'un qui cherchait un getElementsByClassName(). On parse notre
document recursivement et quand on trouve ce qu'on cherche, on l'ajoute directement.
function getComments()
{
function _GetElementsByClass(outArray, seed)
{
while (seed)
{
if (seed.nodeType == Node.ELEMENT_NODE)
{
if (seed.hasAttribute("class") && seed.className == "comment")
outArray.push(seed);
_GetElementsByClass(outArray, seed.firstChild)
}
seed = seed.nextSibling;
}
}
var outArray = new Array();
_GetElementsByClass(outArray, document.documentElement);
return outArray;
}
TreeWalker
A mon avis le plus lisible et le plus flexible: meme sans connaitre on devine ce que fait le code du premier coup d'oeil, et c'est simple a modifier Par ailleurs, on utilise un truc implémenté nativement par le navigateur, on devrait donc etre rapide. Voir plus bah pour la meme chose en plus complexe.
function getComments()
{
function acceptNode(node)
{
if (node.hasAttribute("class") && node.className == "comment")
{
return NodeFilter.FILTER_ACCEPT;
}
return NodeFilter.FILTER_SKIP;
}
var out = new Array();
var treeWalker = document.createTreeWalker(document.body,
NodeFilter.SHOW_ELEMENT,
acceptNode,
false);
if (treeWalker)
{
var node = treeWalker.nextNode();
while (node)
{
out.push(node);
node = treeWalker.nextNode();
}
}
return out;
}
XPath
Donné par Dylan Schiemann en réponse au post de Daniel sur les différentes méthodes
de getElementsByClassName, et redonné par Dam lors de mon récent post sur le TreeWalker et Konqueror, on profite du fait que on manipule du XML, et on utilise XPath.
function getComments()
{
var xpathResult = document.evaluate('//*[@class = "comment"]', document, null, 0, null);
var outArray = new Array();
var item;
while (item = xpathResult.iterateNext())
{
outArray[outArray.length] = item;
}
return outArray;
}
Voyons ce que cela donne. Chaque script a été relancé 10 fois sur un gros (> 700 commentaires) article de
linuxfr tres legement nettoyé, et le cache vidé entre chaque essai.
C'est loin d'etre une méthode tres scientifique, mais ca suffira ici. Les temps sont exprimés en millisecondes,
meme si cela n'est pas tres important vu que par flemme je ne donnerais ni les pages ni les specs de la machine sur laquelle
j'ai fait tourner tout 
- Résultat pour getElementsByTagName(): 200
- Résultat pour Parseur maison: 5000
- Résultat pour TreeWalker: 2400
- Résultat pour XPath: 180
(Rappel: je ne teste pas les différentes implémentations de getElementsByClassName. Je teste différentes manieres
d'utiliser le DOM pour récupérer des commentaires sur linuxfr, en simpliant grandement. Ces chiffres sont donc a
prendre avec des pincettes, ils servent surtout a annoncer d'autres méthodes dans la suite de ce post 
Les résultats sont plutot interessants. J'ai bien tout verifié pour etre sur que je n'hallucinais pas. Vu que c'est pas tellement ce que j'attendais, les conclusions attendront: je vais passer un peu de temps à regarder ce que je peux faire sur la DLFPToolbar au vu de ces résultats.
Edit: Visiblement, je suis pas le seul à m'interesser au probleme. La version svn de prototype a l'air excellente.








Commentaires
En valà un billet qu'il est bien.

Merci
Les résultats sont très surprenants en effet. Je m'interroge juste sur la pertinence du test "naïf". En effet, la méthode getElementByTagName récupère l'ensemble des éléments div contrairement aux autres méthodes qui ne présume pas de l'élément. Cette supposition permet-elle de gagner de précieuses millisecondes ? Quel sont les temps avec un getElementByTagName("*") ?
J'y ai pensé, mais j'ai oublié de tester avec '*'. (J'ai banni cette construction de mon esprit
Je retesterais ce soir si j'y pense.
Par contre, je pensais pouvoir gagner du temps dans le TreeWalker en utilisant NodeFilter.FILTER_REJECT, vu que je sais pas mal de trucs sur ce que j'ai a parser, mais les gains sont minimes, meme en rejettant des grosses parties complexes du document.
Je suis allé de mon petit test aussi
Il semble que la différence avec un getElementsByTagName("*") ne soit pas vraiment significative.
J'ai également testé avec un nodeIterator (identique au TreeWalker mais initialisé avec un document.createNodeIterator). Le client utilisé correspond à Opera puisque Firefox ne les implémente pas correctement. Le résultat est que j'obtiens un facteur trois entre la mode TreeWalker et la façon NodeIterator qui est plus rapide. Par contre avec la version 9p1 d'Opera c’est toujours la version XPAth qui mène la dance.