Infinite scrolling bug in Svelte hex viewer component

Viewed 69

I've been working on creating a hex viewer component that is able to handle the display of arbitrarily large arrays. Upwards of 10s of millions of values are expected. I've managed to get this component mostly working, but there has been an elusive bug that I've been stuck with for days.

The idea is to only render to the DOM what is currently visible on the screen. There are spacer elements above and below the viewport that mimic the displacement of the cells that aren't being rendered.

The relevant component can be found here: https://github.com/DamenH/hex-viewer/blob/master/src/lib/SmartDataGrid.svelte

This function calculates the start and end indices of the array that are currently visible to the viewport, and then changes the visibleCells to contain that range of values.

    function updateVisibleCells() {
      let visibleAreaStart = dataGrid.scrollTop;
      let visibleAreaEnd = dataGrid.scrollTop + height;
      let startIndex = Math.floor(visibleAreaStart / cellHeight) * columns;
      let endIndex = Math.ceil(visibleAreaEnd / cellHeight) * columns;
      endIndex = Math.min(items.length, endIndex);
    
      [currentStartIndex, currentEndIndex] = [startIndex, endIndex];
      visibleCells = items.slice(startIndex, endIndex);
    }

This function calculates the size of the spacers above and below the rendered cells.

    function updateSizes() {
      topSpacerHeight = Math.floor(currentStartIndex / columns) * cellHeight;
      bottomSpacerHeight = 
        Math.floor((items.length - currentEndIndex) / columns) * cellHeight;
    }

The issue.

When scrolling down, be it via the scroll handle, the middle mouse wheel, or dragging the middle mouse button, the scroll starts looping automatically without stopping.

I think what is happening is that there is a loop created to where the top spacer is calculated incorrectly, triggering a scroll event, which continues ad infinitum. What really gets me is that this only happens when scrolling down. Scrolling up is smooth, and as expected. Attempting to change the top spacer to counteract this results in the behavior happening on scroll up as well.

Here is a demo of the component.

https://damenh.github.io/hex-viewer/

I'd really appreciate any help with this.

Update

After some further testing I have discovered that this appears to only happen in Chrome. I have filed a Chrome bug report. I will try to recreate this component with Vue. If the issue persists, that would be very interesting.

0 Answers
Related