Tips & Tricks

Claude Code के साथ Implement Virtual Scrolling कैसे करें

Claude Code का उपयोग करके implement virtual scrolling सीखें। Practical code examples और step-by-step guidance शामिल है।

仮想scrollがज़रूरीな場面

数千〜数万件のlist displayする際、सभीのDOM要素を描画するとブラウザのperformanceが大幅に低नीचेし है।仮想scroll(ウィンドウイング)は、画面に見えている部分だけをDOMに描画する手法 है।Claude Code का उपयोग करके、इस高度なoptimization技術をefficientlyimplementationでき है।

basic 仮想scrollのimplementation

> 固定高さアイテムの仮想scrollcomponentを作って。
> 10万件のlistでもスムーズに動く तरहして。
import { useState, useRef, useCallback, useMemo } from 'react';

interface VirtualListProps<T> {
  items: T[];
  itemHeight: number;
  containerHeight: number;
  overscan?: number;
  renderItem: (item: T, index: number) => React.ReactNode;
}

function VirtualList<T>({
  items, itemHeight, containerHeight, overscan = 5, renderItem,
}: VirtualListProps<T>) {
  const [scrollTop, setScrollTop] = useState(0);
  const containerRef = useRef<HTMLDivElement>(null);

  const totalHeight = items.length * itemHeight;
  const visibleCount = Math.ceil(containerHeight / itemHeight);
  const startIndex = Math.max(0, Math.floor(scrollTop / itemHeight) - overscan);
  const endIndex = Math.min(items.length, startIndex + visibleCount + overscan * 2);

  const visibleItems = useMemo(
    () => items.slice(startIndex, endIndex),
    [items, startIndex, endIndex]
  );

  const handleScroll = useCallback(() => {
    if (containerRef.current) {
      setScrollTop(containerRef.current.scrollTop);
    }
  }, []);

  return (
    <div
      ref={containerRef}
      onScroll={handleScroll}
      style={{ height: containerHeight, overflow: 'auto' }}
      role="list"
      aria-label={`list(全${items.length}件)`}
    >
      <div style={{ height: totalHeight, position: 'relative' }}>
        {visibleItems.map((item, i) => {
          const index = startIndex + i;
          return (
            <div
              key={index}
              role="listitem"
              style={{
                position: 'absolute',
                top: index * itemHeight,
                height: itemHeight,
                width: '100%',
              }}
            >
              {renderItem(item, index)}
            </div>
          );
        })}
      </div>
    </div>
  );
}

可変高さアイテムへのsupport

> アイテムごとに高さが異なる仮想scrollにもsupportして。
class DynamicSizeManager {
  private heights: Map<number, number> = new Map();
  private estimatedHeight: number;

  constructor(estimatedHeight: number) {
    this.estimatedHeight = estimatedHeight;
  }

  setHeight(index: number, height: number) {
    this.heights.set(index, height);
  }

  getHeight(index: number): number {
    return this.heights.get(index) ?? this.estimatedHeight;
  }

  getOffset(index: number): number {
    let offset = 0;
    for (let i = 0; i < index; i++) {
      offset += this.getHeight(i);
    }
    return offset;
  }

  getTotalHeight(itemCount: number): number {
    return this.getOffset(itemCount);
  }

  findIndexAtOffset(offset: number, itemCount: number): number {
    let current = 0;
    for (let i = 0; i < itemCount; i++) {
      current += this.getHeight(i);
      if (current > offset) return i;
    }
    return itemCount - 1;
  }
}

高さ自動計測component

import { useRef, useEffect } from 'react';

function MeasuredItem({ index, onMeasure, children }: {
  index: number;
  onMeasure: (index: number, height: number) => void;
  children: React.ReactNode;
}) {
  const ref = useRef<HTMLDivElement>(null);

  useEffect(() => {
    if (ref.current) {
      const observer = new ResizeObserver(([entry]) => {
        onMeasure(index, entry.contentRect.height);
      });
      observer.observe(ref.current);
      return () => observer.disconnect();
    }
  }, [index, onMeasure]);

  return <div ref={ref}>{children}</div>;
}

TanStack Virtualのutilization

より本格的なimplementationにはTanStack Virtualがconvenient है।

import { useVirtualizer } from '@tanstack/react-virtual';

function VirtualizedList({ items }: { items: string[] }) {
  const parentRef = useRef<HTMLDivElement>(null);

  const virtualizer = useVirtualizer({
    count: items.length,
    getScrollElement: () => parentRef.current,
    estimateSize: () => 50,
    overscan: 10,
  });

  return (
    <div ref={parentRef} style={{ height: 600, overflow: 'auto' }}>
      <div style={{ height: virtualizer.getTotalSize(), position: 'relative' }}>
        {virtualizer.getVirtualItems().map((virtualItem) => (
          <div
            key={virtualItem.key}
            style={{
              position: 'absolute',
              top: 0,
              transform: `translateY(${virtualItem.start}px)`,
              width: '100%',
            }}
          >
            {items[virtualItem.index]}
          </div>
        ))}
      </div>
    </div>
  );
}

Summary

Claude Code का उपयोग करके、固定高さ・可変高さの仮想scroll से、TanStack Virtualのutilization तकefficientlyimplementationでき है।無限scrollとの組み合わせは無限scrollimplementationを、全般的なperformance改善はperformanceoptimizationをदेखें。

TanStack Virtualके details के लिएTanStack Virtualofficial documentationदेखें。

#Claude Code #virtual scrolling #performance #React #ウィンドウイング