Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sluggish scroll behaviour of large(ish) html table in Google Chrome

I am trying to create a large HTML table (around 5000 rows) with scrollbars and so I thought about inserting that table inside a <div> which I could then format as I pleased.

It works well in Firefox 47 and in IE 11 but has a sluggish behaviour on scroll in Chrome 59.

WORKING DEMO

<!DOCTYPE html>
<html>
    <head>
        <title>Test page</title>
    </head>

    <body>
        <div style="width: 400px; height: 300px; overflow: scroll;" id="test"></div>
        <script>
            let table = '<table style="table-layout: fixed; width: 3000px">';
            table += '<thead>';
            table += '<tr>';
            for(let i=0; i < 30; i++) { 
                table += '<th style="width: 100px">#' + i +'</th>';
            }
            table += '</tr>';
            table += '</thead>';
            table += '<tbody>';
            for(let i=0; i < 5000; i++) { 
                table += '<tr>';
                for(let j=0; j < 30; j++) { 
                    table += '<td>r: '+ i +' || c: '+ j +'</td>';
                }
                table += '</tr>';
            }
            table += '</tbody>';
            table += '</table>';
            document.getElementById('test').innerHTML = table;
        </script>
    </body>

</html>

However if I just add the table to the document body, the scroll behaviour is smooth across the 3 browsers I've tested (but I could only observe this behaviour while running the code in my local dev. server; if I append the table to the document body in a JSFiddle the sluggish behaviour of Chrome reappears).

My question is what may be causing this sluggish behaviour of Chrome and what can I do to get a smoother scrolling table?

*Edit: I've removed the style="position: relative" from the <td> in the codeblock because that's how I've done in the Fiddle. I was experimenting with that style because I've noticed that IE tends to get sluggish on scroll when the table elements are positioned relatively. My ultimate goal is to create a large html table with a fixed/frozen header that has a scrollable body with a large number of rows.

like image 411
Moaning Neighbors Avatar asked Jul 17 '17 22:07

Moaning Neighbors


People also ask

How do I fix scrolling lag in chrome?

Type chrome://flags in the Chrome address bar. Scroll down to find the Smooth Scrolling setting. Change the setting from Default to Disabled. Restart Chrome.

How do I speed up scrolling in chrome?

Easy to use To activate the increased speed, hold the Alt key while scrolling.

Does chrome have smooth scrolling?

Google Chrome has a feature that enables you to animate web pages smoothly when scrolling page content. If your Google Chrome seems to be jerky or stuttering when scrolling, you can enable this feature. Open a new tab and type chrome://flags/#smooth-scrolling in the address bar, and press Enter.


1 Answers

Try to add transform: translate3d(0, 0, 0) to the table. An example is given below. That trick is getting old, however. Postings about it reach back to 2012 already. For instance, see this posting.

Currently, browsers [...] ship with hardware acceleration; they only use it when they have an indication that a DOM element would benefit from it. With CSS, the strongest indication is that a 3D transformation is being applied to an element.

In my company, we use it for almost every larger list. Mostly, it works fine. Another solution would be virtualization.

let table = '<table style="table-layout: fixed; width: 3000px">';
table += '<thead>';
table += '<tr>';

for(let i=0; i < 30; i++) { 
  table += '<th style="width: 100px">#' + i +'</th>';
}

table += '</tr>';
table += '</thead>';
table += '<tbody>';

for(let i=0; i < 5000; i++) { 
  table += '<tr>';
  for(let j=0; j < 30; j++) { 
    table += '<td>r: '+ i +' || c: '+ j +'</td>';
  }
  table += '</tr>';
}

table += '</tbody>';
table += '</table>';
document.getElementById('test').innerHTML = table;
document.getElementById('test2').innerHTML = table;
#test {
  -webkit-transform: translate3d(0, 0, 0);
          transform: translate3d(0, 0, 0);
}
<h2>With translate3d</h2>
<div style="width: 400px; height: 300px; overflow: scroll;" id="test"></div>
<h2>Without translate3d</h2>
<div style="width: 400px; height: 300px; overflow: scroll;" id="test2"></div>

(or full snippet)

like image 60
SVSchmidt Avatar answered Oct 01 '22 22:10

SVSchmidt