I am working on a very customized web based diff tool. We collect network device config information before changes are made on the device, then collect the same information after config changes are made. The user is then presented with a highly customized side-by-side diff where irrelevant results are filtered using a different css style than the relevant results. (for example, the uptime would be different, but not relevant).
All this work is done on the server side, and performs well. As one may expect there can be a large number of lines, for example “show interfaces” may easily show upwards of a 1000 lines, for both pre and post, while there may only be a few diff’ed lines to show. What I am trying to implement is a button to hide the irrelevant lines showing only the diff’ed lines. I use the following function to do this…
function run_show_changed_button(command) {
var commandWithDashes = command.replace(/\s+/gi, "-");
var button = $(".show-changed[command='" + command + "']");
var stage = $(button).attr("stage");
var preRows = $("#diff-result-pre-section-" + commandWithDashes + " > .diff-hide");
var postRows = $("#diff-result-post-section-" + commandWithDashes + " > .diff-hide");
if (stage == "all") {
$(preRows).hide();
$(postRows).hide();
$(button).attr("stage", "changed");
$(button).html("<button>Show All</button>");
} else {
$(preRows).each(function() {
$(this).css('display', 'block');
});
$(postRows).each(function() {
$(this).css('display', 'block');
});
//$(preRows).show();
//$(postRows).show();
$(button).attr("stage", "all");
$(button).html("<button>Show Only Changed</button>");
}
}
On hide() this function works quite well, show() also works well on smaller result sets, but on larger result sets the cpu load stays at about 50% (dual core system). As far as I can tell, this load never lowers, and the function never returns. Using chrome’s inspector I can see that the selector returns quickly enough, but the problem appears to be with “recalculating style”. The system memory load doesn’t appear to increasing as the function runs.
I’m getting to the point where I may do this on the server side, but I would like to know how to best address this problem. I’m not married to using jQuery if there is another solution.
[Edited to add html sample]
Sample html used (with sensitive material redacted)
<div class="diff-result-post-section ui-widget wi-widget-content" id="diff-result-post-section-show-interface">
<div class="diff-result-row ordinary-row diff-hide">
<pre style="margin: 0em; padding: 1px;">Something edited out...</pre>
</div>
<div class="diff-result-row ui-state-error">
<pre style="margin: 0em;">Something edited out...</pre>
</div>
<div class="diff-result-row ordinary-row diff-hide">
<pre style="margin: 0em; padding: 1px;">Something edited out...</pre>
</div>
(stuff snipped)
<div class="diff-result-row ui-state-error">
<pre style="margin: 0em;">Something edited out...</pre>
</div>
<div class="diff-result-row ordinary-row diff-hide">
<pre style="margin: 0em; padding: 1px;">Something edited out...</pre>
</div>
</div>
[Solved]
The problem ended up being the amount of work the browser was going through in trying to update each change to the DOM. The solution was to hide the parent element, then update the css elements to set each ‘display’ to ‘block’, then re-show the parent element. The speed of execution was orders of magnitude faster. The code to accomplish this is posted below. You’ll notice I had to add a bit of delay after hiding the parent element before changing the css elements.