Thanks for sharing that you run into the same issue. Agree that something is wrong, perhaps scrolling causes the table to re-render for some reasons. I will look more into it and getting it fix next. There are techniques to optimize performance such as only render visible rows. I haven't spent much time testing it on mobile web and will enhance the mobile web view & experience upcoming.
You don't need to only render visible rows. There are only 400. You just insert them into the Dom and that's it.
Thanks again for your note! You are totally right that something is wrong. I took a closer look and fixed 2 issues that should massively improve the performance now if you would like to try again.
Below are more details--- Issue 1. Table with a link overlay in every cell I initially used an off shelf table component to move fast and didn't take a closer look at the implementation. It turned out this component renders a link overlay in every cell to allow user to click table row to be taken to the job link. So 400 jobs with 6 rows end up rendering 2400 link overlays.
The reason it attaches a link overlay to a cell instead of a row is due to a well known bug with Safari, where you can't use `position: relative` in table row `tr` https://bugs.webkit.org/show_bug.cgi?id=240961. Attaching it to each cell works for small number of rows but causes performance issues with large number of rows.
I fixed it by rolling out my own table with css grid instead. It is not as semantic as it no longer uses table, thead, th, tr, td, but thanks to Safari, it is a tradeoff I am okay with.
Bug 2. Unnecessary re-render on Zustand store rehydrate I used Zustand store to filters preference and save it to browser's local storage. On page load, it fetches from local storage to update the state or store rehydrate . I didn't use shallow comparison initially and caused the table to render even if the prev and new state is an empty array due to comparison by reference. Using shallow comparison minimize an uncessary render.