jaredLunde / jaredLunde/masonic

`scrollToIndex` causing browser to hang/crash with large lists of items

Open
#188 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
1.4k
Forks
63
PR merge metrics
No merged PRs in 30d

Description

**Describe the bug**
We are currently experiencing an issue whilst using the batteries-included `Masonry` component to build an image gallery in our application. The issue we are having is specifically related to the `scrollToIndex` functionality.

For context: The list of images displayed in our gallery can regularly stretch into the thousands. Clicking on an item in the gallery takes the user to another page in our application. When the user clicks "back" or uses the browser back button, they are taken back to the gallery and we wish to take the user back to the same scroll position they were in previously (to save them scrolling again). For this we are using the `scrollToIndex` prop on the `Masonry` component.

When the user is taken back to the gallery, something is causing the browser to hang. None of the items will be visible and the browser is clearly struggling to re-render the gallery. The amount of time the browser 'hangs' is proportional to the density that the user scrolled. For example: scrolling through thousands of assets will cause the browser to hang for ~10+ seconds, whereas barely scrolling at all only causes a minor (~200ms) hang before the items are rendered.

I have tried to profile the error using the React DevTools, but unfortunately this also seems to hang and the profile is never generated. Using the Chrome application profiler doesn't yield anything useful as it simply points to "something" in React blocking the main thread in the browser from rendering.

This is an example of how we're using `Masonry` inside the application to render our gallery:

```

```

Things we have already tried to resolve the error (with no luck):

1. Memoizing all inputs to `Masonry` to reduce the workload needed to render the items in the gallery
2. Stripping back the component we render in the `render` prop to the bare minimum (To clarify, there are 0 useEffect or useState's and the component simply renders an image along with a filename, icon and a button).
3. Trying to calculate the scroll position (in pixels) and using the browser to scroll to that position manually, i.e. `window.scrollTo`

**To Reproduce**
Steps to reproduce the behavior:

1. Scroll through a long (1000+) list of images in a `Masonry` powered image gallery
2. Navigate away from the image gallery, and then back to it, passing in a `scrollToIndex` value
3. Notice that the browser 'hangs' before the image gallery is rendered and the browser scrolls to the correct position

**Expected behavior**
It looks as though every item in the gallery is be re-rendered before `Masonry` attempts to scroll the user back to the `scrollToIndex` value provided. This seems to be the reason for the delay in rendering/browser hanging and why it is related to the number of items in the gallery and how far the user has scrolled in that list.

I would expect that in a virtualized list, re-rendering every item in the gallery should not be necessary as it should only need to render the items relative to the `scrollToIndex` value being provided

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing the issue with the Masonry component, a 1000+ item list, and a large scrollToIndex value. Trace the scrollToIndex path and virtualization behavior to determine whether items are rendered before the target position is applied. Done means returning to the gallery restores the target position without rendering the entire list or hanging the browser.

Written by the indexing model from the issue text.

Assessment

Tech stack
react, typescript
Domain
frontend, performance
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.