1. Diese Seite verwendet Cookies. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies. Weitere Informationen

jQuery: Bilder nachladen, hohe CPU Last

Dieses Thema im Forum "Javascript & Ajax" wurde erstellt von chris4712, 21. Dezember 2016.

  1. chris4712

    chris4712 Erfahrenes Mitglied

    Hallo in die Runde!

    In einem Projekt werden viele DIV Container erzeugt, die je ein kleines Bild als Hintergrundbild haben. Die Container werden anhand einer Datenbankabfrage erstellt. Wenn nun 500 Container auf einmal ein Hintergrundbild laden, geht das in die Hose.
    Also war meine Idee: Immer nur die Bilder zu laden die grade angezeigt werden. Da ich mit "mCustomScrollbar" arbeite, habe ich einfach das Event "whileScrolling" verwendet, was meine Funktion (siehe unten) ausführt.

    Ich gebe also z.B. 100x diese Zeile aus (ID passt sich an):
    PHP:
    1. <div class="ThumbContainer ThumbNotLoaded" id="$Picture["ID"]"></div>
    Die JavaScript Funktion, die beim Scrollen ausgeführt wird, schaut so aus:
    Code (Text):
    1. function ShowThumbs(scrollerTop) {
    2.   var scrollerHeight = $("#ImageSurveyArea").height(); // Liest die Höhe des Bereiches aus, in dem die Bilder angezeigt werden
    3.  
    4.   $(".ThumbNotLoaded").each(function () { // Läuft jedes Bild durch was noch nicht geladen wurde
    5.     // Wenn das Bild sich im sichtbaren Bereich befindet
    6.     if ($(this).position().top >= scrollerTop && $(this).position().top <= (scrollerHeight+scrollerTop)) {
    7.       $(this).html('<div class="ThumbImage" style="background-image: url(\'functions/PictureManager/Thumbnail.php?ID='+$(this).attr('id')+'\')"></div>'); // Neuen DIV Container erzeugen, der das Bild als Hintergrundbild hat
    8.       $(this).removeClass("ThumbNotLoaded"); // Klasse entfernen um zu signalisieren das Bild geladen wurde
    9.     }
    10.   });
    11. }
    Soweit so gut. Klappt wunderbar. Jedoch ist die CPU Last irgendwas bei 30% (Intel Core i7). Kann also nicht der optimale Code sein. Zumal nicht nur 100 Bilder sondern gerne auch mal 1000 Bilder angezeigt werden.

    Wie könnte ich das Konstrukt optimieren?

    Vielen Dank fürs Nachdenken und schöne Grüße!

    Christian
     
  2. Quaese

    Quaese Moderator Moderator

    Hi,

    ich würde an unterschiedlichen Stellen versuchen zu optimieren.

    1. Aufrufen des scroll-Handlers nur, wenn sich die Scrollposition deutlich verändert hat (z.B. 30 Pixel) => damit können sicherlich zahlreiche unnütze Funktionsaufrufe vermieden werden => das würde die Last im Handler reduzieren, ständig die Elemente im DOM zu ermitteln, die noch kein Hintergrundbild-Element besitzen

    2. Häufiger benutzte Anweisungen (z.B. $(this)) in Variablen speichern => damit kann vermieden werden, dass ständig das gleiche Element referenziert werden muss
    Code (Text):
    1. $(".ThumbNotLoaded").each(function () { // Läuft jedes Bild durch was noch nicht geladen wurde
    2.     var $this = $(this),
    3.         top = $this.position().top;
    4.  
    5.     // Wenn das Bild sich im sichtbaren Bereich befindet
    6.     if (top >= scrollerTop && top <= (scrollerHeight+scrollerTop)) {
    7.         $this.html('<div class="ThumbImage" style="background-image: url(\'functions/PictureManager/Thumbnail.php?ID='+$this.attr('id')+'\')"></div>'); // Neuen DIV Container erzeugen, der das Bild als Hintergrundbild hat
    8.         $this.removeClass("ThumbNotLoaded"); // Klasse entfernen um zu signalisieren das Bild geladen wurde
    9.     }
    10. });
    3. Zu guter Letzt würde ich vermeiden, Elemente neu zu erstellen, die ich auch im HTML anlegen bzw. bereitstellen kann.
    PHP:
    1. <div class="ThumbContainer ThumbNotLoaded" id="$Picture["ID"]"><div class="backgroundContainer"></div></div>
    Innerhalb der each-Anweisung kann dann auf das bereits existierende Element zugegriffen werden und das Erstellen und Einhängen in den DOM kann entfallen.
    Code (Text):
    1. $(".ThumbNotLoaded").each(function () { // Läuft jedes Bild durch was noch nicht geladen wurde
    2.     var $this = $(this),
    3.         $elem= $this.children().eq(0),
    4.         top = $this.position().top;
    5.  
    6.     // Wenn das Bild sich im sichtbaren Bereich befindet
    7.     if (top >= scrollerTop && top <= (scrollerHeight+scrollerTop)) {
    8.         // Hintergrundbild an Element zuweisen
    9.         $elem.css({
    10.             'background-image': 'url(functions/PictureManager/Thumbnail.php?ID=' + $this.attr('id') + ')'
    11.         });
    12.         // Klasse entfernen, um zu signalisieren, dass das Bild geladen wurde
    13.         $this.removeClass("ThumbNotLoaded");
    14.     }
    15. });
    Kannst das ja mal ausprobieren und hier mitteilen, ob und welchen Erfolg das gebracht hat.

    Ciao
    Quaese
     
    sheel gefällt das.
Die Seite wird geladen...