Improving iScroll performance on a large table

2019-03-24 05:39发布

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?

https://jsfiddle.net/0qv1kjac/16/

8条回答
贪生不怕死
2楼-- · 2019-03-24 06:37

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.

  1. Go old school and add a horizontal and vertical scrollbar. I know it's not a pretty solution but it would work well.

  2. 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.

查看更多
倾城 Initia
3楼-- · 2019-03-24 06:38

Just use ClusterizeJS! It can handle hundreds of thousands of rows and was built exactly for this purpose.

How does it work, you ask?

The main idea is not to pollute DOM with all used tags. Instead of that - it splits the list to clusters, then shows elements for current scroll position and adds extra rows to top and bottom of the list to emulate full height of table so that browser shows scrollbar as for full list

查看更多
登录 后发表回答