I’ve got a large table that lists out approximately 50 users and some simple data around their accounts, including the number of “projects” they have. When clicking on a user row more rows expand beneath to reveal detailed information about each of their projects. Most users have fewer than 20 projects, so it’s not terribly taxing on the browser. However, there are a few users that have 100+ projects (one with 500+) and when clicking on the user row the browser stalls for anywhere from 1-4 seconds.
The table rows are set up so that any row with the .project class is hidden by default, and when clicking on a user row (no .project class) all subsequent rows with the .project class have the class .open added which displays them.
Suggestions on how to make this run faster? Is there a better, cleaner way to achieve the same effect?
Here is a simplified version of the HTML:
<table>
<tr>
<td>Username</td><td>Email</td><td>10 Projects</td>
</tr>
<tr class="project">
<td> </td><td> </td><td>Project Name</td>
</tr>
<tr class="project">
<td> </td><td> </td><td>Project Name</td>
</tr>
<tr class="project">
<td> </td><td> </td><td>Project Name</td>
</tr>
<tr class="project">
<td> </td><td> </td><td>Project Name</td>
</tr>
<tr class="project">
<td> </td><td> </td><td>Project Name</td>
</tr>
<tr class="project">
<td> </td><td> </td><td>Project Name</td>
</tr>
<tr class="project">
<td> </td><td> </td><td>Project Name</td>
</tr>
<tr class="project">
<td> </td><td> </td><td>Project Name</td>
</tr>
<tr class="project">
<td> </td><td> </td><td>Project Name</td>
</tr>
<tr class="project">
<td> </td><td> </td><td>Project Name</td>
</tr>
<tr>
<td>Username</td><td>Email</td><td>3 Projects</td>
</tr>
<tr class="project">
<td> </td><td> </td><td>Project Name</td>
</tr>
<tr class="project">
<td> </td><td> </td><td>Project Name</td>
</tr>
<tr class="project">
<td> </td><td> </td><td>Project Name</td>
</tr>
</table>
… and the JS:
(function($) {
$.fn.viewProjects = function() {
this.each(function() {
$(this).click(function(){
var projects = $(this).nextUntil(':not(.project)'); // get all rows that follow and have the '.project' class
if ($(this).hasClass('focused')) { // collapse
$(this).removeClass('focused');
projects.each(function(n, proj){
$(proj).removeClass('open');
});
}
else { // expand
$(this).addClass('focused');
projects.each(function(n, proj){
$(proj).addClass('open');
});
}
});
});
};
$('tr:not(.project)').viewProjects();
})(jQuery);
This is because the DOM is loading so much added stuff in to it. What I do in similar situations is:
Alternatively, you can automatically trigger the next 50 rows to load when the user scrolls down the page. I prefer showing a link because automatically loading stuff can be confusing.
Edit – What if you use jQuery to show and hide the contents instead of adding and removing a class each time?