dash icon indicating copy to clipboard operation
dash copied to clipboard

Jumpy scroll in a Dash DataTable

Open Coding-with-Adam opened this issue 3 years ago • 1 comments

When scrolling the DataTable on a mobile phone, the DataTable is jumpy.

Issue first reported on Forum

The community member created this sample app to replicated the problem. They also shared the code for the app on GitHub.

Coding-with-Adam avatar Sep 20 '22 17:09 Coding-with-Adam

I'm the one, who reported the issue on the forum, feel free to ping if I can be of any help.

timofeymukha avatar Sep 20 '22 19:09 timofeymukha

Hello! Is there a chance someone will take a look at this in the foreseeable future :-)?

timofeymukha avatar Nov 24 '22 12:11 timofeymukha

Thanks @timofeymukha - in fact I see jumpy scrolling in your onrender example even in a wide window, but it gets substantially worse as the window gets narrower.

It's going to be a little while before anyone here is able to work on it, but I can provide some pointers into the code in case someone wants to try and contribute a fix. The key issue is that as we have it right now, virtualized tables assume all rows are the same height and calculate how many rows to drop at the beginning based on this. And to a certain extent we NEED to guess at the row heights, because it's crucial for performance that we not render every row above the ones we're looking at.

The height is measured here:

https://github.com/plotly/dash/blob/a834e5a52e083c90fff85dfc8d338bb4d8df3ba1/components/dash-table/src/dash-table/components/ControlledTable/index.tsx#L199-L209

and used to calculate how many rows to drop here:

https://github.com/plotly/dash/blob/a834e5a52e083c90fff85dfc8d338bb4d8df3ba1/components/dash-table/src/dash-table/derived/data/virtualized.ts#L44

and to calculate the marginTop for how much scroll space to leave above the visible cells here:

https://github.com/plotly/dash/blob/a834e5a52e083c90fff85dfc8d338bb4d8df3ba1/components/dash-table/src/dash-table/derived/table/fragmentStyles.ts#L27-L35

So when you scroll and we add or remove rows at the top and we modify marginTop, I think the thing to do will be to alter scrollTop as well based on how different the actual heights of these rows are from what we were expecting.

Exactly how to do this I'm not 100% sure - but first guess is we should stash the actual vertical positions and row numbers of the first and last rendered rows somewhere - maybe in uiViewport state? Or perhaps we need a new state variable so we don't rerender unnecessarily... And then either the first or last rendered row will be available post-scroll and can be used to adjust scrollTop.

After that, we can expect the scrollbar position to be a little bit jumpy, but the contents should be smooth.

alexcjohnson avatar Nov 29 '22 22:11 alexcjohnson