0

I am trying to populate an empty list using an array of photo names. I have made this work already, but with a large amount of photos it can become relatively slow. More than 500 photos is not unusual.

I am wondering if someone could find a way to make this code work faster, or tell me what make this code run slow so I can have another look at it myself.

The code I have is as follows. this.photoListElement is a jQuery object referring to the unordered list element. photoNames is an array of photo name strings. Variables are declared at the top of the function which is not shown here. isThumbDownloaded checks a variable in an object. getThumb and getThumbId are functions which add some strings together.

(...)
place = [];
for(i=0; i< photoNames.length; ++i) {
    photoName = photoNames[i];
    if(coverages.isThumbDownloaded(coverageId, photoName)){ // A function which checks if a photo is downloaded. If it is, the photo should not be hidden, and the right background should be applied.
        bg = 'background-image:url(\''+coverages.getThumb(coverageId, photoName) + '?' + new Date().getTime()+'\');';
        cls = '';
    } else {
        bg = '';
        cls = 'hidden';
    }
    place[i] = '<div id="'+ this.getThumbId(photoName) +'" photoName="'+photoName+'" style="'+bg+'" class="phoPhoto '+cls+'" onclick="$.mobile.changePage($(\'#carousel\'), {transition: \'slidefade\'})"></div>';
}
this.photoListElement.html(place.join(''));
(...)

Help is very much appreciated.

After research

The problem is not the loop, although some minor optimizations can be done, but the the dom insertion.

Aart Stuurman
  • 3,188
  • 4
  • 26
  • 44
  • I'm not using strict mode in this function. Would that make a difference at all? – Aart Stuurman Jul 02 '13 at 12:13
  • Loading 500 image files just is slow. Do you really think you need to do this? – Bergi Jul 02 '13 at 12:17
  • What is `coverages.isThumbDownloaded` supposed to do if you're using a cachebuster right after it? – Bergi Jul 02 '13 at 12:19
  • Does the code complete fairly quickly, and it's just the images that are slow to be loaded and rendered? – MrCode Jul 02 '13 at 12:19
  • @Bergi I'm at a point where I don't want to change the way I load photos anymore. At the moment it takes about 300-500ms, which is not that bad, but I wanted to see if I can speed it up. – Aart Stuurman Jul 02 '13 at 12:21
  • @MrCode I did not think of that. Let me check. – Aart Stuurman Jul 02 '13 at 12:21
  • @Bergi I don't know what you mean by cachebuster. Could you explain? – Aart Stuurman Jul 02 '13 at 12:22
  • @Bergi I have checked, and the loop itself runs fairly fast(30ms for 500 photos). The join is also fast. The problem is with the appending I guess. – Aart Stuurman Jul 02 '13 at 12:31
  • 1
    It sounds like the whole code completes quickly, and the browser is just slow at requesting and rendering 500 images. If you think the div concatenation is the problem, try building the DOM element using `document.createElement('div')` and work with the object instead of building raw HTML. That should be faster but it could only be slightly. – MrCode Jul 02 '13 at 12:35
  • So you would recommend creating each photo div seperately, and append them all seperately too? – Aart Stuurman Jul 02 '13 at 12:37

2 Answers2

1

In the loop you are counting the number of photoNames on each iteration:

for(i=0; i< photoNames.length; ++i)

Keep the length in a variable instead and the loop will be faster:

for (var i = 0, ilen = photoNames.length; i < ilen; i += 1)

Also, string concatenation might be faster than array join, check this jsperf .

So:

place = "";

...

place += '<div>.......';

..

this.photoListElement.html(place);
Community
  • 1
  • 1
Emil A.
  • 3,387
  • 4
  • 29
  • 46
0

Try using

$('ul').append(ilen);

WinHtaikAung
  • 414
  • 2
  • 11