Skip to content

madebyaman/virtualizer

Repository files navigation

virtualizer

A high-performance virtualization library for rendering large lists and tables efficiently. Only renders visible items with a custom scrollbar, dramatically reducing DOM nodes and improving performance for datasets with thousands or millions of rows.

features

  • efficient rendering - only renders items currently visible in the viewport
  • smooth scrolling - custom scrollbar with optimized scroll handling
  • framework agnostic - works with React, vanilla JS, or any framework
  • TypeScript support - fully typed APIs
  • row reusing - recycles DOM nodes for better garbage collection performance
  • lightweight - minimal dependencies

performance

this library is designed to handle extremely large datasets efficiently:

  • tested with 500,000+ rows
  • only renders ~15-20 DOM nodes regardless of total dataset size
  • smooth 60fps scrolling even on 6X CPU slowdown (tested on M1 Macbook Pro)
  • minimal memory footprint through DOM node recycling

installation

npm install
npm run dev

usage

react example

using the useVirtualScroll hook for a virtualized table:

import { useVirtualScroll } from './hooks/useVirtualScroll';

function VirtualizedTable() {
  const ROW_HEIGHT = 40;
  const TOTAL_ROWS = 100000;
  const VIEWPORT_HEIGHT = 600;

  // Initialize virtual scroll
  const { scrollbar, virtualizer } = useVirtualScroll({
    count: TOTAL_ROWS,
    size: ROW_HEIGHT,
    viewportSize: VIEWPORT_HEIGHT,
  });

  const renderedIndices = virtualizer.renderedIndices;
  const containerProps = scrollbar.containerProps;
  const thumbProps = scrollbar.thumbProps;

  return (
    <div
      {...containerProps}
      style={{
        ...containerProps.style,
        height: `${VIEWPORT_HEIGHT}px`,
        overflow: 'hidden',
      }}
    >
      <div style={{ position: 'relative' }}>
        {renderedIndices.map((rowIdx) => {
          const position = rowIdx * ROW_HEIGHT - scrollbar.position;
          return (
            <div
              key={rowIdx}
              style={{
                position: 'absolute',
                height: `${ROW_HEIGHT}px`,
                transform: `translateY(${position}px)`,
                width: '100%',
              }}
            >
              Row {rowIdx}
            </div>
          );
        })}
      </div>

      {/* Custom scrollbar thumb */}
      <div
        {...thumbProps}
        style={{
          ...thumbProps.style,
          width: '12px',
          background: '#ccc',
          borderRadius: '6px',
        }}
      />
    </div>
  );
}

api reference

VirtualScroll class

interface VirtualScrollOptions {
  count: number;           // total number of items
  size: number;            // height of each item in pixels
  viewportSize: number;    // height of the visible viewport
  onChange?: (instance: VirtualScroll) => void;  // callback on scroll
}

const virtualScroll = new VirtualScroll(options);

properties:

  • virtualizer.renderedIndices - array of indices currently in viewport
  • virtualizer.height - total content height
  • scrollbar.position - current scroll position
  • scrollbar.containerProps - props to attach to scroll container
  • scrollbar.thumbProps - props to attach to scrollbar thumb

methods:

  • updateOptions(options) - update virtualization options
  • cleanup() - clean up event listeners

react hook: useVirtualScroll

const { scrollbar, virtualizer } = useVirtualScroll({
  count: number;
  size: number;
  viewportSize: number;
});

future enhancements

the following features are planned for future releases:

  • fixed size DOM nodes for GC optimization
  • horizontal scrolling & full grid support
  • touch events support
  • filter/sort/search functionality using workers and sharedArrayBuffer
  • dynamic height support

license

MIT

contributing

contributions are welcome! please feel free to submit a pull request.

About

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published