I'm updating a table header and its first column positions programatically based on how the user scrolls around to keep them aligned.
The issue I'm experiencing is that as soon as my data sets gets big enough, the scrolling gets more and more choppy/less smooth.
The relevant code is at the very bottom of the fiddle:
iScroll.on('scroll', function(){
var pos = $('#scroller').position();
$('#pos').text('pos.left=' + pos.left + ' pos.top=' + pos.top);
// code to hold first row and first column
$('#scroller th:nth-child(1)').css({top: (-pos.top), left: (-pos.left), position:'relative'});
$('#scroller th:nth-child(n+1)').css({top: (-pos.top), position:'relative'});
// this seems to be the most expensive operation:
$('#scroller td:nth-child(1)').css({left: (-pos.left), position:'relative'});
});
I know that this can be written a lot more efficent by caching the elements and so on. For example, I have tried saving the elements in to an array and updating their position in a more "vanilla" fashion:
headerElements[i].style.left = left + 'px'; // etc...
No matter how fast I make the callback, I'm still not happy about the result. Do you have any suggestions?
This won't be the answer your are looking for but here's my 2 cents anyway.
Javascript animation (especially given the amount that the DOM has to render) will never be as smooth as you want it. Even if you could get it smooth on your machine, chances are that it will vary drastically on other peoples (Older PC's, Browsers etc).
I would see 2 options if I were to tackle this myself.
Go old school and add a horizontal and vertical scrollbar. I know it's not a pretty solution but it would work well.
Only render a certain amount of rows and discard those off screen. This could be a bit complicated but in essence you would render say 10 rows. Once the user scrolls to a point where the 11th should be there, render that one and remove the 1st. You would pop them in and out as needed.
In terms of the actual JS (you mentioned putting elements in to an array), that isn't going to help. The actual choppyness is due to the browser needing to render that many elements in the first place.
Just use ClusterizeJS! It can handle hundreds of thousands of rows and was built exactly for this purpose.
How does it work, you ask?