Tips & Tricks

Cara Implement Virtual Scrolling dengan Claude Code

Pelajari cara implement virtual scrolling menggunakan Claude Code. Dilengkapi contoh kode praktis dan panduan langkah demi langkah.

仮想scrollがdiperlukanな場面

数千〜数万件 リスト tampilan 際、すべて DOMelemen 描画 dan browser performa 大幅 低下.仮想scroll(ウィンドウイング) 、画面 見えて部分だけ DOM 描画 手法.Claude Code 使えば、こ 高度なoptimasi技術 efisien implementasi bisa dilakukan.

implementasi dasar的な仮想scroll

> 固定高さアイテム 仮想scrollkomponen buatkan.
> 10万件 リスト dengan juga スムーズ 動くよう.
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={`リスト(全${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>
  );
}

dukungan 可変高さアイテムへ

> アイテムご dan 高さ 異なる仮想scroll juga dukunganして。
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;
  }
}

高さ自動計測komponen

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>;
}

pemanfaatan TanStack Virtual

より本格的なimplementasi TanStack Virtual praktis.

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

Untuk Claude Codeを使えば、固定高さ・可変高さの仮想scrollから、TanStack Virtualのpemanfaatanまでefisienにimplementasiできます。無限scrollとの組み合わせは無限scrollimplementasiを、全般的なperformapeningkatan, lihat パフォーマンス最適化.

TanStack Virtual 詳細 TanStack Virtual公式dokumen silakan lihat.

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