2

My JQuery script which does a lot of DOM manipulation works smoothly in Chrome (expected), runs very well in Safari and not so badly in Firefox.

Lets talk about internet explorer...

When I run a method that does a bit of DOM manipulation the following code causes the page to go white for about 1 second while it processes. The line that is effecting speed quite a lot is commented:

function AutoAssignImage(sourceImageDiv, destinationHolder) {
    // Check nothing is assigned
    if (!$(destinationHolder).has('.upload-pane-item').length) {
        sourceImageDiv.find('.quickAssign').hide();
        sourceImageDiv.find('.unassign').show();
        sourceImageDiv.css({ border: "0px" });

        $(destinationHolder).html(sourceImageDiv); // Causes blank screen while moves dom element

        // Update Quick Assign buttons
        updateQuickAssignButtons();
    }
}

function updateQuickAssignButtons() {
    quickAssign = "string gets generated here but is very quick";

    $('#' + uploadPaneId + ' .quickAssignLinks').html(quickAssign); // Very slow

}

I need to update the HTML that is used on up to 500 elements. I have tried using a loop thinking it would update the first few elements almost instantly and could process the others while the user would not notice the slight delay. When I tried using a .each() JQuery loop it didn't seem to make any different and still causes a white screen for about a second.

EDIT: The HTML that is commonly set is like the following:

<a class="assignLink" href="#">1</a>
<a class="assignLink" href="#">2</a>
<a class="assignLink" href="#">3</a>
<a class="assignLink" href="#">4</a>
<a class="assignLink" href="#">5</a>
<a class="assignLink" href="#">6</a><br />
<a class="assignLink" href="#">7</a>
<a class="assignLink" href="#">8</a>
<a class="assignLink" href="#">9</a>
<a class="assignLink" href="#">10</a>
<a class="assignLink" href="#">11</a>
<a class="assignLink" href="#">12</a>

Caching

I have tried storing the elements in a variable to enable some form of caching

var quickAssignElements; // top of js file
quickAssignElements = $('#' + uploadPaneId + ' .quickAssignLinks'); // called when DOM updates

$(quickAssignElements).html(quickAssign); // Calls this when it needs to update html on elements

This didn't seem to make a difference either.

Does anyone know of an alternative approach to minimise the delay / stop the window going blank?

Andrew
  • 9,967
  • 10
  • 64
  • 103
  • @Andi That code has a syntax error in the selector. – Šime Vidas Apr 06 '11 at 12:38
  • Thanks, I've updated. It was inserted by accident just on this code snippet it is correct in my live code :) – Andrew Apr 06 '11 at 12:39
  • @Andi One solution would be to use timers. I recommend you to watch this excellent talk which discusses your issue: http://vimeo.com/16241085 – Šime Vidas Apr 06 '11 at 12:44
  • Are you updating just the text inside the elements? Or are you adding more nodes to the DOM? – John Strickler Apr 06 '11 at 12:45
  • could you give me a little source, this would help me posting a correct answer. – Gergely Fehérvári Apr 06 '11 at 12:45
  • I'm pretty sure jQuery uses each internally on most methods so that's probably why it didn't make any difference. – Alex Apr 06 '11 at 12:50
  • @omnosis I've edited to show what html is displayed – Andrew Apr 06 '11 at 12:59
  • i mean the JS code which do the update. I understand that there is hundreds of links, and you manipulate them, but i i think you need to optimize your code. – Gergely Fehérvári Apr 06 '11 at 13:00
  • Hard to give much more from above without posting the whole file which I can't do. I've updated with the method that I'm calling and that is slow. Thanks for your time, appreciate it – Andrew Apr 06 '11 at 13:13
  • use http://pastebin.com to paste the whole file if you want, btw i have a question: is these different? .quickAssignLinks != .assignLinks – Gergely Fehérvári Apr 06 '11 at 13:19
  • quickAssignLinks is the parent div container – Andrew Apr 06 '11 at 13:21
  • i cant figure ot what is the problem exactly. you give me crumbs of source, i am trying to figure ot the problem, but i cant help you whith this if you not provide a ormal sorce. i can tell that the blank screen is not caused by the .html() stuff. there is something more. please give a normal source. WHOLE javascript and HTML – Gergely Fehérvári Apr 06 '11 at 13:29
  • Have added to JS code, I'm not able to post the whole file and HTML due to the nature of the work but hope the snippet is enough to assist. Thanks – Andrew Apr 06 '11 at 13:44

1 Answers1

1

You need to see which call is slow on your page. It might be $('#MyDiv .myClass'), or it might be .html('...'), or both. If it's just the first one, the easy solution is to select those elements only once, and store them in a variable that you can access the next time to need to call .html() on them. In jQuery-talk, this is typically called "caching."

There are a number ways you can make the selector itself more efficient, too.


Edit

Since you showed us what your markup looks like, I can almost guarantee that this selector method will be faster:

$('#MyDiv').find('a.myClass');
Community
  • 1
  • 1
Matt Ball
  • 354,903
  • 100
  • 647
  • 710
  • tried caching it previously didn't make a difference. Added in more info to my question – Andrew Apr 06 '11 at 13:08
  • So the slow part isn't the selector? Or are you only calling `.html()` on that group once? – Matt Ball Apr 06 '11 at 13:09
  • It seems to be the point when it is updating the elements html not the selecting of the elements. The group of elements are dynamic so when one of the elements is assigned to something the links change and a given link is removed. – Andrew Apr 06 '11 at 13:24
  • 2
    @Matt This is even a bit more faster: `$('a.myClass', '#MyDiv')` (and the code is smaller) – Šime Vidas Apr 06 '11 at 13:30
  • 1
    @Šime I thought that internally, `$('selector', 'context')` was converted to `$('context').find('selector')`. – Matt Ball Apr 06 '11 at 13:54
  • @Matt Yes, you're right. This is exactly what jQuery does internally. The performance difference is negligible. – Šime Vidas Apr 06 '11 at 14:21