js auf Internet Explorer
artnat
- javascript
Ich habe zwei lokale Sites, von denen die eine seit langem auf allen Browsern gut funktioniert, aber weiterentwickelt werden musste. Daraus entstand die Site 2. Beide enthalten ein längeres Javascript, das bei der zweiten Version nur unwesentlich verändert wurde. Die zweite Version läuft auf allen Browsern mit Ausnahme des Internet-Explorer gut. Dort aber läut die zweite Version extrem langsam bzw. das Skript wird beendet. Der Script Debugger des Iexplore zeigt aber keinen Fehler an.
Ich weiß, dass Iexplore manchmal anders reagiert, als andere Browser. Ich las gerade im Internet, dass jemand berichtete, ein Javascript sei im Iexplore extrem langsam gewesen, weil er eine Variable deklariert, aber nicht verwendet hatte. Gibt es irgendwelche bekannten Probleme mit JS, irgendwelche normalerweise funktionierenden Dinge, die der Iexplore nicht mag?
Hallo artnat,
... seit langem auf allen Browsern gut funktioniert ... weiterentwickelt ... nur unwesentlich verändert ... Internet-Explorer ... extrem langsam bzw. das Skript wird beendet.
zwei Nachfragen: welcher IE und was wurde geändert?
Gruß, Jürgen
Hallo Jürgen,
zwei Nachfragen: welcher IE und was wurde geändert?
Internet Explorer 9.
Änderung: vor allem habe ich den Inhalt von Formulartexten beim ersten durch die Dokument-Kinder-Kette document.formname.textname[j] angesprochen, während ich sie beim zweiten über document.getElementsByName("textname")[j] angesprochen habe. Sonst finde ich nichts wesentliches.
artnat
Hi,
Änderung: vor allem habe ich den Inhalt von Formulartexten beim ersten durch die Dokument-Kinder-Kette document.formname.textname[j] angesprochen, während ich sie beim zweiten über document.getElementsByName("textname")[j] angesprochen habe. Sonst finde ich nichts wesentliches.
das ist aber scho was Wesentliches. Denn in der vorherigen Version
document.formname.textname[j]
muss die JS-Engine beim Zugriff nur das Formular nach Elementen mit dem gewünschten Namen durchsuchen, in der geänderten Fassung
document.getElementsByName("textname")[j]
jedoch das gesamte Dokument. Warum hast du das überhaupt geändert?
Mag sein, dass andere Browser den DOM-Baum besser indizieren und dadurch beim Durchsuchen schneller sind als der IE, so dass der Unterschied bei denen nicht so deutlich auffällt.
Ciao,
Martin
Hallo ihr Lieben,
vielen Dank für Eure Antworten. Ich habe inzwischen versucht, bei der langen Dauer die der Iexplore brauchte (35 sec statt 3-4sec auf anderen Browsern) durch Zwischenausgaben die Zeit für einzelne Programmteile zu ermitteln. Dabei hat sich gezeigt, dass das eigentliche Programm, das ich für den Schuldigen hielt, ganz flott läuft. Der Schuldige war ein kleines Progrämmchen, das in der anschließend aufgerufen Seite läuft, und das früher nicht existierte. In diesem Programm laufen zwei Schleifen, eine über ca. 4000 Indizes und eine über ca. 10 Indizes. Während es bei allen anderen Browsern keinen Unterschied macht, welche die innere und welche die äußere Schleife ist (es bleiben ja so oder so 40000 Auswertungen) läuft der Iexplore viel schneller, wenn die große Schleife außen ist. Warum ??? Kann mir das jemand sagen?
Jedenfalls ist jetzt der Iexplore zwar immer noch etwas langsamer, aber nicht, wie bisher um einen Faktor 10.
Fall ist ziemlich abgeschlossen.
Hallo artnat,
... Während es bei allen anderen Browsern keinen Unterschied macht, welche die innere und welche die äußere Schleife ist (es bleiben ja so oder so 40000 Auswertungen) läuft der Iexplore viel schneller, wenn die große Schleife außen ist. Warum ??? Kann mir das jemand sagen?
dazu müsste man wissen, was in den Schleifen gemacht wird. Code?
Gruß, Jürgen
Hallo Jürgen
hier der Code:
i läuft von 0 bis ca. 3740
j läuft von 0 bis zu einer Zahl zwischen 2 und 300.
Dieser Code läuft auf Iexplore langsam:
for (i=1 ; i<llis; i++ )
{
for (j=0 ; j<document.getElementsByTagName("h1").length; j++)
{
if (liste[i]==document.getElementsByTagName("h1")[j].firstChild.data)
{
document.writeln("<div id=\"v-briefeintrag\"><a href=\"..\/briefe\/" + liste[i] + ".htm\">" + document.getElementsByTagName("h2")[j].firstChild.data + "<\/a><\/div>")
document.writeln("<div id=\"v-inhalt\">" + document.getElementsByTagName("h3")[j].firstChild.data + "<\/div>")
}
}
}
Dieser Code läuft etwa 4 mal so schnell:
for (j=0 ; j<document.getElementsByTagName("h1").length; j++)
{
for (i=1 ; i<llis; i++ )
{
if (liste[i]==document.getElementsByTagName("h1")[j].firstChild.data)
{
document.writeln("<div id=\"v-briefeintrag\"><a href=\"..\/briefe\/" + liste[i] + ".htm\">" + document.getElementsByTagName("h2")[j].firstChild.data + "<\/a><\/div>")
document.writeln("<div id=\"v-inhalt\">" + document.getElementsByTagName("h3")[j].firstChild.data + "<\/div>")
}
}
}
Auf den anderen Browsern kann ich den Unterschied nicht gut messen, weil die Zeiten immer bei wenigen Sekunden liegen.
Ich weiß jetzt auch den Grund für den Unterschied. Es ist die immer wieder neue Auswertung der Obergrenze von j als document.getElementsByTagName("h1").length. Wenn ich diesen Wert vor der Schleife einer Variablen übergebe, sind beide Codeversionen gleich schnell.
Vielen Dank für die Diskussion, Finish, artnat
[latex]Mae govannen![/latex]
Dieser Code läuft etwa 4 mal so schnell:
for (j=0 ; j<document.getElementsByTagName("h1").length; j++)
{
for (i=1 ; i<llis; i++ )
{
if (liste[i]==document.getElementsByTagName("h1")[j].firstChild.data)
{
document.writeln("<div id="v-briefeintrag"><a href="../briefe/" + liste[i] + ".htm">" + document.getElementsByTagName("h2")[j].firstChild.data + "</a></div>")
document.writeln("<div id="v-inhalt">" + document.getElementsByTagName("h3")[j].firstChild.data + "</div>")
}
}
}
Was ist mit (ungetestet)
~~~javascript
var h1coll = document.getElementsByTagName("h1"),
h2coll = document.getElementsByTagName("h2"),
h3coll = document.getElementsByTagName("h3"),
hlen = hcoll.length;
for (j=0; j<hlen; j++)
{
for (i=1 ; i<llis; i++ )
{
if (liste[i]==hcoll[j].firstChild.data)
{
document.writeln("<div id=\"v-briefeintrag\"><a href=\"..\/briefe\/" + liste[i] + ".htm\">" + h2coll[j].firstChild.data + "<\/a><\/div>")
document.writeln("<div id=\"v-inhalt\">" + h3coll[j].firstChild.data + "<\/div>")
}
}
}
wobei ich document.writeln auch zugunsten der DOM-Methoden vermeiden würde.
Stur lächeln und winken, Männer!
Kai
Hallo Kai345,
da warst du schneller.
Gruß, Jürgen
Hallo,
wobei ich document.writeln auch zugunsten der DOM-Methoden vermeiden würde.
Was hieße: Ein Container-Element oder DocumentFragment erzeugen, dort – im Speicher – alle Elemente anhängen, erst am Ende diesen Container ins DOM einhängen.
Allerdings muss das DOM nicht unbedingt schneller sein und der Browser wird genauso einfrieren, wenn die Schleife längere Zeit läuft. Das müsste man dann in kleinere Häppchen aufteilen.
Mathias
Hallo artnat,
for (j=0 ; j<document.getElementsByTagName("h1").length; j++)
{
for (i=1 ; i<llis; i++ )
{
if (liste[i]==document.getElementsByTagName("h1")[j].firstChild.data)
{
document.writeln("<div id="v-briefeintrag"><a href="../briefe/" + liste[i] + ".htm">" + document.getElementsByTagName("h2")[j].firstChild.data + "</a></div>")
document.writeln("<div id="v-inhalt">" + document.getElementsByTagName("h3")[j].firstChild.data + "</div>")
}
}
}
Zugriffe auf Arrays, Objekte oder gar Domelemente sollte man in Schleifen wenn möglich vermeiden. Daher solltest du die Zugriffe auf "h1", "h2" und "h3" außerhalb der i-Schleife durchführen und zwischenspeichern:
~~~javascript
e_h1 = document.getElementsByTagName("h1");
e_h2 = document.getElementsByTagName("h2");
e_h3 = document.getElementsByTagName("h3");
in der j-Schleife:
e_h1j = e_h1[j];
e_h2j = e_h2[j];
e_h3j = e_h3[j];
und dann in der i-Schleife
e_h1.length
, e_h1j.firstChild.data
, e_h2j.firstChild.data
oder e_h3j.firstChild.data
Der Zugriff auf liste erfolgt nur zweimal in der i-Schleife, hier erwarte ich von einem Zwischenspeichern keinen großen Gewinn.
Gruß, Jürgen
Hi,
Änderung: vor allem habe ich den Inhalt von Formulartexten beim ersten durch die Dokument-Kinder-Kette document.formname.textname[j] angesprochen, während ich sie beim zweiten über document.getElementsByName("textname")[j] angesprochen habe. Sonst finde ich nichts wesentliches.
document.formname.textname ist eine Collection, die der Browser selbst zusammenstellt. Sie liegt vor, enthält Referenzen und kann direkt angesprochen werden.
document.getElementsByName("textname") ist eine Methode. Sie wird bei jedem Aufruf ausgeführt und tut, was sie tun soll - nämlich im Wesentlichen die Collection zusammenstellen, die bei der vorherigen Vorgehensweise schon vorlag.
Mit anderen Worten: Aus "Gib mir mal die Akte Neumayer." ist "Such mal alle Daten vom Neumayer zusammen und mach 'ne Akte daraus, die Du mir dann gibst." geworden.
Cheatah