3

I have some performance problems with jQuery. Therefore I want to try my loop with the lenght of 7000 with JS than jQuery. Because I read, that jQuery has always very bad performance.

I tried to convert my jQuery Selector to JS, but it stills not working:

from:

var i;
for (i = 0; i < e.detail.length; i++){
    $("iframe").contents().find(".timeline-node[title='" + i + "']").css("background-image", "url( \"imgs/" + e.detail[i] + ".png \") ");
}

to :

var i;
for (i = 0; i < e.detail.length; i++){
   document.getElementById('#iframe').querySelector("[title=\"" + i + "\"]").css("background-image", "url( \"imgs/quality_3/" + e.detail[i] + ".png \") ");
}

The error of my new code is: Cannot read property 'querySelector' of null at HTMLDocument. I think JS cannot find my title with attr. i. But my code with jQuery works very well, but it takes 80sec. to do it for 7000 indexes.

Sam Toorchi
  • 133
  • 1
  • 9

1 Answers1

3

Query iframe only once

var i, iframe = document.querySelector('iframe').contentWindow.document;
for (i = 0; i < e.detail.length; i++){
   iframe.querySelector("[title=\"" + i + "\"]").style.backgroundImage = "url( \"imgs/quality_3/" + e.detail[i] + ".png \") ";
}

You could try to use only one query and filter results instead

document.querySelector("iframe").contentWindow.document.querySelectorAll("[title]").forEach(function (elm) {
    var id = +elm.getAttribute("title");
    if (id < e.detail.length) {
        elm.style.backgroundImage = "url( \"imgs/quality_3/" + e.detail[id] + ".png \") ";
    }
});

Multi iframe version

document.querySelectorAll("iframe").forEach(function (iframe) {
    iframe.contentWindow.document.querySelectorAll("[title]").forEach(function (elm) {
        var id = +elm.getAttribute("title");
        if (id < e.detail.length) {
            elm.style.backgroundImage = "url( \"imgs/quality_3/" + e.detail[id] + ".png \") ";
        }
    })
});

Performance comparison

console.time("loop");
var i;
for(var a = 0; a < 10; a++) {
  for (i = 0; i < 20; i++){
     document.querySelector("[title=\"" + i + "\"]");
  }
}
console.timeEnd("loop")

console.time("singleQuery");
var i;
for(var a = 0; a < 10; a++) {
   document.querySelectorAll("[title]").forEach(function(elm) { 
     if(+elm.getAttribute("title") < 20) { 
      // change background 
     }
   });
}
console.timeEnd("singleQuery")
<p title="0"></p>
<p title="1"></p>
<p title="2"></p>
<p title="3"></p>
<p title="4"></p>
<p title="5"></p>
<p title="6"></p>
<p title="7"></p>
<p title="8"></p>
<p title="9"></p>
<p title="10"></p>
<p title="11"></p>
<p title="12"></p>
<p title="13"></p>
<p title="14"></p>
<p title="15"></p>
<p title="16"></p>
<p title="17"></p>
<p title="18"></p>
<p title="19"></p>
ponury-kostek
  • 7,824
  • 4
  • 23
  • 31
  • @mplungjan Dupe is about getting iframe content, not performance improvement – ponury-kostek May 15 '19 at 14:29
  • First issue is getting it at all, no? Then inserting 7000 images into the DOM is going to take a while regardless – mplungjan May 15 '19 at 14:44
  • @mplungjan OP says that script executes in 80 sec, in my second example it should be much faster – ponury-kostek May 15 '19 at 14:47
  • Wow, It looks very good now, but I have just one Error: "Cannot read property 'style' of null at HTMLDocument". But all my Divs with the element title have a style="". Do you know why JS cannot find the style? – Sam Toorchi May 15 '19 at 14:59
  • @mplungjan Yes I tested. Check code snippet – ponury-kostek May 15 '19 at 15:05
  • @samTT show line that gives you an error – ponury-kostek May 15 '19 at 15:06
  • @ponury-kostek I just tested the second version, and it works very find, and it need just 1 second to do everything. Thank you very much! I have just one more problem. I have in my index.html 7 iframes. But know you code takes the first iframe and do the tasks on it. I tried with querySelectorAll for the ('iframe'), but I become the Error: "Cannot read property 'document' of undefinedat HTMLDocument" at the first line of code and red underlined "document.querySelectorAll("[title]..." Can you maybe help me just one more time? :) – Sam Toorchi May 15 '19 at 15:14
  • @samTT see updated answer – ponury-kostek May 15 '19 at 15:18
  • @ponury-kostek everything works perfect, and you helped me so much! Thank you very much for your time and help! :) – Sam Toorchi May 15 '19 at 15:20
  • @samTT you welcome – ponury-kostek May 15 '19 at 15:24