GreenAssaulter: Image in for-Schleife 7000 Mal zuweisen

Hallo,

ich möchte ein HTML-Dokument, in dem ein kleines Image (~1KB) über 7000 Mal wiederholt vorkommt, im Speicherbedarf minimieren, d. h. die IMG-Tags möglichst kurz machen, indem ich die SRC-Angabe im IMG-Tag spare. Ausserdem empfiehlt es sich natürlich, das Bild einmal vorzuladen. Dazu habe ich folgenden Ansatz:

1. Das Image kommt im Dokument jedesmal gleich in der Form <IMG id="dieID"> vor

2. Das BODY-TAG des Dokuments enthält den JavaScript-Funktionsaufruf onload="setImages()"

3. setImages() sieht folgendermassen aus:

function setImages(){

// Vorladen des Images:
   var bild = new Images();
   bild.src = "/Pfad/DasBild.gif";

// Zuweisen an die IMG-Tags über die ID "dieID" in einer Schleife:
   var coll = document.all.dieID;
   for ( i = 0 ; i < coll.length ; i++){
      coll(i).src = bild.src;
   }
}

Die for-Schleife wird also über 7000 durchlaufen. Auch wenn ich in der Schleife keinerlei Anweisung stehe habe, dauert allein das schon ewig (40 Sekunden auf einem P4 mit 1,8 GHz und 512 MB RAM).

Ist da irgendwas falsch? Gibt es einen alternativen Weg?

Gruss,

Jan

  1. Hi,

    ich möchte ein HTML-Dokument, in dem ein kleines Image (~1KB) über 7000 Mal wiederholt vorkommt,

    Da ist doch irgendwas im Konzept krank, wenn Du 7000mal das gleiche Bild anzeigen willst.

    1. Das Image kommt im Dokument jedesmal gleich in der Form <IMG id="dieID"> vor

    Das ist schon der erste Fehler. Eine ID darf höchstens einmal pro Dokument vorkommen.

    var coll = document.all.dieID;

    spätestens hier werden alle Nicht-IE-Browser einen Fehler werfen.

    cu,
    Andreas

    --
    MudGuard? Siehe http://www.mud-guard.de/
    1. hello

      Da ist doch irgendwas im Konzept krank, wenn Du 7000mal das gleiche Bild anzeigen willst.

      selbst wenn es 7000 verschiedene bilder sind, mal überschlagsmässig und gnädig mit 20k pro bild gerechnet, ergibt das über 9mb... da freut sich der nicht flatrate surfer... :)

      abgesehen davon kanns sein das sich manche brauser bei der fülle an bildern eh verabschieden....
      nabend,
      hoagie

      1. Hi,

        selbst wenn es 7000 verschiedene bilder sind, mal überschlagsmässig und gnädig mit 20k pro bild gerechnet, ergibt das über 9mb... da freut sich der nicht flatrate surfer... :)

        Bei 7000 Bildern a 20k liegt man DEUTLICH über 9MB - nämlich bei 140MB...

        cu,
        Andreas

        --
        MudGuard? Siehe http://www.mud-guard.de/
        1. Meine Applikation ist ein dynamischer Tree, der Statusinformationen eines Konzerns beinhaltet. Man kann sehr wohl eine ID mehrfach vergeben , auch wenn man das nicht sollte. Wie gesagt ist das Bild max. 1KB gross. Im übrigen funktioniert mein Ansatz (im IE, woanders braucht es nicht zu laufen), nur dass das Durchlaufen der Loop so so lange dauert. Im Übrigen ist die Applikation auch nicht für ganz normale Surfer gedacht.

          Hi,

          selbst wenn es 7000 verschiedene bilder sind, mal überschlagsmässig und gnädig mit 20k pro bild gerechnet, ergibt das über 9mb... da freut sich der nicht flatrate surfer... :)

          Bei 7000 Bildern a 20k liegt man DEUTLICH über 9MB - nämlich bei 140MB...

          cu,
          Andreas

          1. Moin!

            Man kann sehr wohl eine ID mehrfach vergeben , auch wenn man das nicht sollte.

            HTML-seitig kann man das natürlich schon. Aber es ist richtig böse, wenn du Javascript und CSS einsetzen willst.

            Und das W3C hat es verboten - reicht das als Begründung? :)

            Ich sehe übrigens den wirklichen Vorteil deiner Vorgehensweise nicht. Was spricht dagegen, einfach 7000 Mal das Bild rein mit HTML einzubinden? Wenn du einen vernünftigen Server hast, der mod_gzip unterstützt, dann komprimiert sich diese dauernde Wiederholung auf schätzungsweise 100 Byte für diesen Teil des Quelltextes zusammen. Da kannst du mit Javascript niemals gegenanstinken.

            Denn vermutlich wird der Browser ständig viel Zeit mit dem Neu-Rendern der zugewiesenen Bilder verbringen. Da du ins <img> keine Größenangaben gesetzt hast, ist dieser Vorgang, der jedesmal eine Veränderung im Seitenlayout bringt, weil der "broken image"-Platzhalter natürlich nicht dieselbe Größe, wie dein Bild hat, besonders aufwendig. Alle 6999 nachfolgenden Bilder müssen neu angeordnet werden.

            Die Bildgröße deines einzelnen Bildes ist hierbei übrigens nicht wirklich entscheidend (obwohl der Browser natürlich so doof sein könnte, 7000 Kopien im Speicher zu halten) - ein guter Browser holt das Bild einmal vom Server und 6999 Mal aus dem Cache.

            - Sven Rautenberg

            --
            Die SelfHTML-Developer sagen Dankeschön für aktuell 21205,05 Euro Spendengelder!
            1. Hallo Sven,

              Denn vermutlich wird der Browser ständig viel Zeit mit dem Neu-Rendern der zugewiesenen Bilder verbringen. Da du ins <img> keine Größenangaben gesetzt hast, ist dieser Vorgang, der jedesmal eine Veränderung im Seitenlayout bringt, weil der "broken image"-Platzhalter natürlich nicht dieselbe Größe, wie dein Bild hat, besonders aufwendig. Alle 6999 nachfolgenden Bilder müssen neu angeordnet werden.

              "Hase und Igel":

              Nach jedem Schleifendurchlauf wird gerendert -
              deshalb auch: "40 Sekunden auf einem P4 mit 1,8 GHz und 512 MB RAM" ;-)

              gruesse
              rainer groth

              --
              ss:| zu:} ls:& fo:) de:] va:| ch:] n4: rl:? br:$ js:| ie:| fl:( mo:?
              (--> einer der letzten bauhaeusler <--)
              1. Hallo,

                "Hase und Igel":

                Nach jedem Schleifendurchlauf wird gerendert -
                deshalb auch: "40 Sekunden auf einem P4 mit 1,8 GHz und 512 MB RAM" ;-)

                nicht nur das. Wirklich richtig viel Zeit kostet

                var coll = document.all.dieID;

                wie es scheint, baut der IE diese Arrays erst dann auf, wenn sie abgefragt werden.

                Mir ist das in einem anderen Optimierungsprojekt aufgefallen, da gab es einen signifikanten Performance-Gewinn, nachdem die Anzahl der Elemente reduziert wurden.

                GreenAssaulter,

                für dein Problem könnte folgende Lösung möglich sein:

                statt eines Bildes, generierst du einen Span- oder Divbereich.

                <span class="statusimage1"></span>

                und dieser Klasse verpasst du ein Hintergrundbild

                .statusimage1 {
                 background-image:url(deineURL);
                 background-repeat:no-repeat;
                 width:20px;
                 height:20px;
                }

                damit ersparst du dir, die Schleife mit JS. Soll das ganze noch anklickbar sein, dann verpasse dem Bereich zusätzlich den Eventhandler onclick und der Klasse die Eigenschaft cursor:pointer;

                Viele Grüße

                Antje

                1. Hallo Anja,

                  die Idee ist an sich ganz gut, danke. Habe eine Variante mit <a>-Tags ausprobiert, die auch funktioniert und noch kürzer ist. Mir ist dabei allerdings  aufgefallen, dass der gesamte Seitenaufbau länger dauert (das Aufklappen des Trees dauert länger), was ich darauf zurückführe, dass das Bild nicht aus dem Cache sondern jedes Mal komplett neu geladen wird. Wenn ich also die Image-Source im <IMG>-Tag angebe, "merkt" der Browser, dass das immer das gleiche Bild ist, wenn die Image-Source aber als Klassenbestandteil (Background-Angabe) in style.css definiert ist, wird immer wieder neu geladen...

                  Hallo,

                  "Hase und Igel":

                  Nach jedem Schleifendurchlauf wird gerendert -
                  deshalb auch: "40 Sekunden auf einem P4 mit 1,8 GHz und 512 MB RAM" ;-)

                  nicht nur das. Wirklich richtig viel Zeit kostet

                  var coll = document.all.dieID;

                  wie es scheint, baut der IE diese Arrays erst dann auf, wenn sie abgefragt werden.

                  Mir ist das in einem anderen Optimierungsprojekt aufgefallen, da gab es einen signifikanten Performance-Gewinn, nachdem die Anzahl der Elemente reduziert wurden.

                  GreenAssaulter,

                  für dein Problem könnte folgende Lösung möglich sein:

                  statt eines Bildes, generierst du einen Span- oder Divbereich.

                  <span class="statusimage1"></span>

                  und dieser Klasse verpasst du ein Hintergrundbild

                  .statusimage1 {
                   background-image:url(deineURL);
                   background-repeat:no-repeat;
                   width:20px;
                   height:20px;
                  }

                  damit ersparst du dir, die Schleife mit JS. Soll das ganze noch anklickbar sein, dann verpasse dem Bereich zusätzlich den Eventhandler onclick und der Klasse die Eigenschaft cursor:pointer;

                  Viele Grüße

                  Antje

        2. achja *hahah*
          mathe nicht genügend, setzen *gg*

          1. Hi hoagie,

            achja *hahah*
            mathe nicht genügend, setzen *gg*

            Wer, du?
            Genauer gesagt ind es 136,72 MB...
            Bei den Bildgrößen, die GreenAssaulter erwähnte, wären es immer noch 6,84 MB...

            Gruß

            Kurt

            --
            > Nein, ich beantworte keine Anfragen per e-mail.
            "Der Erfolg zaehlt. Die Misserfolge werden gezaehlt."  (Nikolaus Cybinski; dt. Aphoristiker; geb. 1936)
            http://elektro-dunzinger.at
            http://shop.elektro-dunzinger.at
            1. hi,

              achja *hahah*
              mathe nicht genügend, setzen *gg*

              Wer, du?

              ja, sicher ich , immerhin hab ich mich "verrechnet" *G*

  2. Hallo!

    Also ich kenne zwar nicht das Einsatzgebiet des Scripts, aber warum schreibst du nicht einfach den Quelltext dynamisch in das Dokument, anstatt jeder id ein anderes src zuzuweisen?

    var zeilenumbruch =  100;
    var j = zeilenumbruch;

    for(i=0;i<=7000;i++)
     {
      document.write('<img src="blabla.jpg">');
      if(i==j)
       {
        document.write('<br>');
        j=j+zeilenumbruch;
       }
     }

    Habs zwar nicht ausprobiert, aber so ungefähr stelle ich mir das vor.

    Oder nimm dir ein Grafikprogramm und Kachel die einzelnen Bilder in ein großes Bild.

    Btw.: document.all ist nur für den IE. Benutze document.getElementById("id"), um das Problem zu verhindern. Mehr dazu auf SelfHTML.

    Gruß

    Mastershrimp

    P.S.: Wozu braucht man bitte 7000 Bilder?

  3. Hallo,

    eine ID darf nur einmal vorkommen!

    Ich verstehe Dein Problem nicht so ganz. Wenn Du immer das selbe Bild laden willst, kein Problem, das steht im Cache des Browsers. Wenn du im IMG-Tag die src-Angabe sparen willst, wähle kurze Namen, z.B. b.gif, das macht pro Bild 11 Byte, also 77kb. Ich glaube, dafür lohnt sich der Aufwand mit dem Script nicht. Ansonsten habe ich mit dynamischen Bildern (und deren Positionierung, siehe Link) auch die Erfahrung gemacht, dass es nicht gerade schnell geht. Javascript wird eben interpretiert und nicht kompiliert.

    Gruß,   Jürgen

  4. Hi,

    warum nimmst du nicht einfach so was:

    <div style="width: ((bildhöhe)*(wieoftnebeneinander));
    ... background-image: url(irgendwas);"></div>

    E7