8

I have quite a large HTML table (2000+ rows) and I'm noticing that the hovers I use seem really unresponsive (take about 1 second to trigger).

#songs tbody tr:hover td { color: #1abc9c; }

I need the table to be loaded with all elements in the DOM. They don't have to be visible per se, so lazy loading is an option but when a user scrolls quite a bit to the bottom he will still run into the problem.

Is there any way to optimize HTML (tables), and what are things I should look out for?

EDIT

I decided to try it out in other browsers and Firefox doesn't seem to have any problem at all, and neither does IE10. So it's a problem I only have in Chrome.

<tr data-playlist="/edm" data-filename="Chuckie - Together (Original Mix).mp3" class="song match">
    <td>Together (Original Mix)</td>
    <td>Chuckie</td>
</tr>

Also note that it's not about the page load, it loads in under a second. The problem is the CSS .song:hover in Chrome.

EDIT 2: Performance testing with the Chrome developer tools

So I decided to take a look into the Developer tools for debugging this problem. The Profiles tab didn't get me much further, but when I tried the Timeline events I found out the following happens when I hover over a row:

enter image description here

Cas Cornelissen
  • 616
  • 8
  • 29
  • 1
    maybe give this a look -> http://stackoverflow.com/a/8648980/1609496 – Mini John Feb 03 '14 at 15:37
  • Forgive me if I'm missing something, but with that many rows shouldn't you paginate them or is that not an option? – patricksweeney Feb 03 '14 at 15:37
  • Thanks for the tip, I'll look into it. Any idea why this is only in Chrome though? – Cas Cornelissen Feb 03 '14 at 15:39
  • And pagination isn't really an options since I want to be able to just keep scrolling (thus lazy loading is an option). It's a list of songs on a server which I want to play so I can't have any reloads/redirects either. – Cas Cornelissen Feb 03 '14 at 15:40
  • @TheMiniJohn, I tried most of the tips in your link (including the classes), but it didn't help much... Any other ideas? – Cas Cornelissen Feb 03 '14 at 16:13
  • 1
    Do you have an javascript on the page? Is your only CSS what you note above? Here's a nice page https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Tips_for_authoring_fast-loading_HTML_pages - Could you give us one "row" of your table as an example? – TimSPQR Feb 03 '14 at 16:31
  • I do have an external JavaScript file on the page which has jQuery click handlers for several things (nothing on the table itself yet)... And I added an example of a row of the table. – Cas Cornelissen Feb 03 '14 at 17:37
  • Maybe try making your CSS selector more "local" like "tr.song { color: .. }" instead of making the browser look all the way up to find the song id outside the big table. – Julian Feb 03 '14 at 17:52
  • I'm not sure if that would work though, since the link that @TheMiniJohn posted in his first comment states "Better than either of those is a class. I used .row in my demo."... – Cas Cornelissen Feb 03 '14 at 17:58

3 Answers3

3

Sooooo, I tried using the different tabs in the Chrome Developer Tools and ran an Audit (if it's possible to say it that way). It stated that 98% of foundation.min.css was unused, so I got rid of the include in my <head>.

And that did it! Since I wasn't really using anything from Foundation at all I simply removed it and the CSS hovers are now instant like they should be.

Cas Cornelissen
  • 616
  • 8
  • 29
  • 2
    Interesting. To figure out what is going on, you can add the include again. When hovering over a table row, the developer tools will show you which styles are being applied to the table. That should give you an idea which of the styles might need so much performance. I think the Chrome guys would be interested in such a bug report. – Aaron Digulla Feb 04 '14 at 08:47
  • I'll definitely will look into that later today! Thanks for the tips as to how to find this problem. – Cas Cornelissen Feb 04 '14 at 18:55
1

This is not really an answer, but rather some "raw" data. So if the mods think it inappropriate, just let me know and I'll delete it.

This question was very intriguing to me because of issues of CSS HTML and JS "overhead" (that's why I asked about any attached CSS or JS).

On THIS page the author did a comparison of load times for divs vs tables and found NO significant difference. So, what about CSS vs JS overhead?

So, because of my neurosis, I put together a 2,000 row table and uploaded it to my site. Nothing fancy, empty table. Then style was added to change background color on third td:

table {
     width: 500px;
     margin: 10px auto;
     border-collapse: collapse;
}
table td {
     width: 30%;
     height: 20px;
     border: 1px solid black;
     border-collapse: collapse;
} 
table td:last-child {
     background-color: red;
}

Then using F12 tools in IE9 mode, the following data were given:

HTTP request: 73.16ms
Style calculation 12.35ms
Style paint 0.5ms

Then the last CSS style was removed and the following JS was added at the end with inclusion of jQuery, jQuery UI, and the jQuery CSS style sheet in head - to act "like" the prior CSS:

$('table tr td:last-child').mouseover(function(){
    $(this).css('background-color', 'red');
    });
$('table tr td:last-child').mouseout(function(){
    $(this).css('background-color', 'transparent');
    });

And the following data were obtained:

HTTP request: 252.25ms
Mouseover: 0.54ms
Layout: 18.7ms
Paint: 1.01ms
Mouseout: .38ms
Style: 0.066ms

So no real surprises - HTTP request is more that triple due to loading jQuery stuff.

Total time to "paint" a td with CSS 12.85ms, with jQuery 20.7ms.

But not a huge difference.

I've learned on this site that whenever possible do everything in CSS. I'm guessing mostly for browser purposes. But at least there's some object evidence of timing advantages (again, no surprise).

Great question, Cas!

TimSPQR
  • 2,964
  • 3
  • 20
  • 29
  • Awesome tests! Of course I was doing the hovers in CSS already and the problem was the `foundation.min.css`, but interesting results nonetheless. – Cas Cornelissen Feb 03 '14 at 21:48
0

You may want to look at the JavaScript performance tools built into Chrome.

A 1 second timeout is a bit long, especially for Chrome. My guess is that something else happens that you don't expect. A table with 2000+ rows shouldn't be a problem as such unless each cell itself contains half a megabyte of HTML :-)

That said, to optimize table, you can assign each table column a fixed width. You can do that with CSS by giving each th/td in the table a class with a fixed width. See this question: Set the table column width constant regardless of the amount of text in its cells?

That will help the browser to optimize the rendering. But I doubt that this will help in your case (fixed column widths usually only help during the initial page rendering).

Community
  • 1
  • 1
Aaron Digulla
  • 321,842
  • 108
  • 597
  • 820
  • I'm already using the fixed with technique (and `table-layout: fixed`). And my table contains just two columns with a single line of text (no elements whatsoever), so that is ruled out too... I'll look into the performance tools! – Cas Cornelissen Feb 03 '14 at 17:35
  • I did some fiddling around in the Developer tools and edited my original answer. Any other ideas? – Cas Cornelissen Feb 03 '14 at 17:58