seymour.co.za

Rendering large HTML tables

I recently had to improve the rendering (front-end) of a large HTML table and had such great results that I decided to write up a blog post about it.

Here’s what the table look like:

Large table

The table had about 7 or 8 columns and about 3000 rows. Using Chrome’s performance analyser, I could observe that the 2 largest time consumers for the page load were javascript and the DOM rendering.

Trial 1 Trial 2 Trial 3
Trial 1 Trial 2 Trial 3

Optimising JavaScript

I already knew what javascript was slowing the page. I had 2 links in each row of the table that needed to be initialised so a popup form would appear when clicked. All 3000 rows would have 2 popup handlers initialised at page load.

Popup form

If you don’t know what part of your JS was slowing down the page, you can find out quite easily by following the call tree.

Call tree

To fix this I only initialise the link on first click. It’s a tradeoff between time on page load vs. time on click. The time on click is so fast that it was worth it (when actually clicking a link, there’s no noticeable increase in the time taken for the popup to appear).

Here’s the performance improvement after this:

Trial 1 Trial 2 Trial 3
Trial 1 Trial 2 Trial 3

The total scripting time was reduced from an average of 1936.4ms to 392.7ms (that’s 4.9x faster).

Optimising DOM rendering

After observing the page loading, I thought that as the table loads, the column widths are constantly adjusted. I made the columns fixed width but this actually didn’t improve the page load time at all.

While doing this, I noticed that if I didn’t have the tab displayed on my screen (i.e. I was in another tab) the page would load much faster. At this point I realised that if the entire table was just rendered in one fell swoop (instead of rendering each row as it loads), then it would render much faster. So, I displayed a spinner until the page was fully loaded, then un-hid the table on page load. The results were also pretty good:

Trial 1 Trial 2 Trial 3
Trial 1 Trial 2 Trial 3

The total rendering time reduced from an average of 1454.8ms to 957.2ms (1.5x faster).

Conclusion

I managed to reduce the page load time by 2041.3ms (scripting and rendering is now 2.5x faster) with very little decrease in usability. Hope you found this useful - I was trying to demonstrate just how important frontend benchmarks and optimisations are, because often when we think about improving performance, we only think about the backend.