9

I have an HTML table that can be more than 1K rows and a dozen or so columns.

I want the columns to be a fixed size (controllable by the user) and not grow/shrink either vertically or horizontally. So visually the contents of a particular table cell will be on one line and the overflow gets cut off at the end of the cell.

Doing performance analysis in Chrome on a large table the main performance killer is overflow:hidden.

I've tried putting the contents of each cell inside of an input, since that would replicate the same visual behavior, but that has a similar performance impact.

What do people recommend to improve performance?

If necessary I don't have to use a table tag, but would prefer to stick with the table tag if good performance can be achieved.

Update 1: I've included a file that demonstrates the performance issue here. Warning the file is pretty massive (25MB) and will slow down your computer. By default the table does not have overflow set to hidden, and once the table has been loaded (can take a while) the browser performance relatively smoothly.

However, if you edit the file and uncomment lines 12-15 and then open it. You'll see after loading browser around the table is significantly less responsive.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Omar Ismail
  • 217
  • 3
  • 7
  • 3
    Is there a reason you aren't using pagination? – Michael Christensen May 15 '12 at 22:56
  • Many reasons actually. Primarily from a UX perspective. But you may have a situation where you have just 100 rows and the person is on a slow computer. Improving performance won't just benefit users with lots of data, but everyone. – Omar Ismail May 15 '12 at 23:06
  • Could you post a sample of the markup and styles you're using? Here: https://gist.github.com/2705929 I have set up an 12x1800 table, with 400+ characters per cell. The performance seems fine (though I'm not on a slow machine). – Ben Hull May 15 '12 at 23:22
  • Also, could you be more specific on the performance you're concerned with? Initial rendering time, scrolling, searching, DOM manipulation, etc... – Ben Hull May 15 '12 at 23:23
  • General browser performance after the table has loaded. Scrolling, clicking, etc. – Omar Ismail May 15 '12 at 23:28
  • The gistfile you posted the content rests inside of a div that is overflow hidden. The way I have things structured now is the content is text directly in the td (ex: lorem ipsum...) with styling on the td {white-space:nowrap; overflow:hidden; width:50px;} – Omar Ismail May 15 '12 at 23:31
  • Any news here? I have the same issue. – JGoodgive Jan 16 '19 at 15:51

4 Answers4

3

FYI: I have run into this problem on the iPad/iOS causing performance problems with a page that has about a hundred rows in a table with table-layout:fixed.

As soon as a cell, or a div in a cell, gets an attribute that forces it the cell to be drawn individually, it takes about 300ms instead of 100ms to draw (which causes the UI to feel abysmally slow for my situation).

Either of two properties (position:relative or overflow:hidden) caused the problem for me, removing them optimised the speed but caused text overflow if cell text was too wide for the fixed width columns.

The slowdown was happening even after tables were drawn, because I am dynamically popping up an absolute div over the table. When profiling the javascript (using (new Date).getTime()), the slowdown in measured in places in the javascript that have nothing to do with the table.

[edit: added following as part solution]

  1. Put all cell content inside a span element (so can measure offsetWidth of content rather than width of containing block element).
  2. After appending the row into the document, test if each span.offsetWidth is greater than the column width, if so add the "overflow:hidden" to the style (or via a class) of the containing block.
  3. Can skip 1 and 2 above for some columns (if it is known that the cell content will never need clipping).

Caveats:

  1. Measurements only made for iOS5 Safari (I didn't profile any other browser).
  2. Works for us because we dynamically create table rows (processing your example using javascript would be slow?).
  3. Most cells for our data do not overflow (clipping is only required sparsely - only a limited number of cells).
  4. Compromised initial page load (generation of table in page went from 80ms to 800ms).
  5. But sped up dynamic combo popup (340ms down to 130ms) giving much better keyboard responsiveness.

For your situation, might be fast to first using variable width columns, measure offsetWidth of all columns, setting column widths to pixel widths and setting overflow:hidden only on columns where offsetWidth of column is greater than the pixel width you will be using for the column.

robocat
  • 5,293
  • 48
  • 65
2

You could try using a tiled approach. It is a pretty typical approach to making things like infinitely side-scrollable games efficiently.

Put all of your data into a Javascript array, and then have N + 1 rows in a table that has N rows visible. When you scroll down, the last item would move into view. At the moment that you have scrolled far enough that the first item moves out of view, you shift all of the data up a row and reset the scroll position back to where it started. Done correctly, the shift would be completely transparent to the user. You would only ever be working with N + 1 rows in an N-rows-visible table.

I've done this before, but under very specific UI constraints. I kind of shutter at the thought of making this consistent using the built-in browser scrollbars and such.

1

first off, the amount of markup required to have a table is much larger than just using divs with clear:both css for a new row. so that's the first performance hit.

also, you are setting the overflow as a class ( ? )

 <style type="text/css"> .ovfl { overflow:hidden; }</style>

  <td class="ovfl"></td>

As an aside, 1000 rows is a weight to deliver.

With divs you at least have an easier opportunity to throw those out of sight ( beyond the scroll ) into a div with display:none until the visitor scrolls to them.

few skins to cat mostly likely on this job,

Hope had some good thoughts.

Rob Sedgwick
  • 5,216
  • 4
  • 20
  • 36
1

Webkit bug 75001 is related to this problem and it covers the work being done to solve it (also see bugzilla dependencies for information).

robocat
  • 5,293
  • 48
  • 65