molily: XPath -> Dieses Forum : Optimierung möglich?

Beitrag lesen

/* Anzahl ungelesene Nachrichten */

Wenn du diese Info zuerst herausziehen willst, ergibt es Sinn, die Knotenliste dann auch weiterzuverwenden.

Wie du vielleicht gesehen hast, frage ich zusätzlich noch ab, ob der Browser den Link bereits als visited markiert hat. Denn wenn man ein Posting gelesen hat, bekommt man die Forumshauptseite immer noch ohne class=visited ausgeliefert, weil stark gecacht wird und die Threadliste nur bei neuen Postings neu ausgeliefert wird.

Nun blende ich einen Link ein, der auf den _ersten_ ungelesenen Beitrag im letzen (d.h. am tiefsten auf der Seite stehenden) Thread verweist. In ungelesene[ug_count-1] finde ich den letzten ungelesenen Beitrag, daher hole ich mir mit ancestor::li[contains(@class,'thread-start')] den Knoten dieses Threads und gehe von da wieder abwärts, um den ersten ungelesenen Beitrag zu ermitteln:

Möglich ist das, ich würde verschiedene Methoden ausprobieren und die Performance testen.

Z.B. manuelles DOM-Traversing: den Thread-Starter holen, dann von hinten durch ungelesen iterieren und bei jedem Knoten prüfen, ob er noch Kind vom Thread-Starter ist (mit contains() bzw. compareDocumentPosition()). Ich habe solche halb-XPath-halb-DOM-Lösungen noch nicht ausprobiert, es kann sein, dass sie schneller sind.

Ein paar Beobachtungen:

  • Eine lange XPath-Abfrage, die etwas wiederholt, was man vorher schon abgefragt hat, kann immer noch schneller sein, als wenn man durch das erste Result-Set iteriert und eine oder mehrere Abfrage(n) von den bereits gefundenen Knoten aus startet.
  • XPath ist lahm. Ich bin dazu übergegangen, querySelector(All) zu verwenden, wo es geht. getElementsByClassName ist am schnellsten.

var t = ungelesene[ug_count - 1].getNodesByXPath("ancestor::li[contains(@class,'thread-start')]/descendant::li[not(contains(@class, 'visited'))]/descendant::span[contains(@class, 'posting')]/descendant::a");

Scheint mir überkomplex, weil auch das a-Element class=visited hat.

Vielleicht ist das schneller:

ancestor::li[contains(@class,'thread-start')]/descendant::a[contains(@class, 'title') and not(contains(@class, 'visited')) and position() = 0]

(Bin aber auch kein XPath-Ass. Nur aus der Hüfte geschossen.)

Mathias