skills/virtualization-specialist/SKILL.md
Implement high-performance list virtualization for 100K+ item datasets using TanStack Virtual and react-window. Activate on: large lists, infinite scroll, windowing, virtual scroll, table with 1000+ rows. NOT for: lists under 100 items (use standard map), pagination-only (use data-fetching-strategist).
npx skillsauth add curiositech/windags-skills virtualization-specialistInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Render 100K+ item lists and tables at 60fps by only mounting visible DOM nodes using TanStack Virtual, react-window, and custom windowing.
Dataset size + requirements?
├─ 100-1000 items, fixed height → react-window (FixedSizeList)
├─ 1000-10K items, variable height → react-virtuoso (auto-sizing)
├─ 10K+ items, need full control → TanStack Virtual
└─ Grid with 1M+ cells → TanStack Virtual 2D + column virtualization
Content type?
├─ Chat messages (variable height) → TanStack Virtual + measureElement
├─ Data table (fixed columns) → TanStack Virtual + TanStack Table
├─ Image gallery (uniform grid) → react-window GridList
└─ File explorer (tree structure) → TanStack Virtual + custom expand/collapse
Scroll behavior pattern?
├─ Smooth scrolling (trackpad) → overscan: 3-5 items
├─ Fast scroll/keyboard → overscan: 8-15 items
├─ Mobile touch scroll → overscan: 5-8 items
└─ Programmatic scroll-to-index → overscan: 2-3 items
Performance constraints?
├─ Mobile/low-end device → Lower overscan (3-5), prioritize memory
├─ Desktop/high-end → Higher overscan (10-15), prioritize smoothness
└─ Slow render time per item → Reduce overscan to minimize work
Content predictability?
├─ Known fixed height → estimateSize: () => FIXED_HEIGHT
├─ Predictable range → estimateSize: (index) => getEstimatedHeight(items[index])
├─ Completely dynamic → measureElement + estimateSize fallback
└─ Mixed content types → Conditional measureElement based on item type
Flickering White Space
overscan too low or estimateSize severely underestimatingScroll Position Jumping
scrollMargin preservation, batch height updatesMemory Bloat Over Time
Infinite Fetch Loop
hasNextPage logic broken or fetch trigger too aggressiveKeyboard Navigation Breaking
scrollToIndex on focus, maintain focus state outside virtualizerScenario: Chat app with 50K messages, variable heights (text + images)
Novice approach: Renders all 50K messages → 7-second load time, browser freeze
// ❌ Renders everything
messages.map(msg => <MessageBubble key={msg.id} message={msg} />)
Expert reasoning:
Implementation:
const virtualizer = useVirtualizer({
count: messages.length,
getScrollElement: () => parentRef.current,
estimateSize: (index) => {
const msg = messages[index];
return msg.type === 'image' ? 200 : 60; // Better estimation
},
overscan: 5,
measureElement: (el) => el?.getBoundingClientRect().height ?? 60,
});
// Expert catches: stable keys, position preservation, loading states
Expert catches vs novice misses:
Don't virtualize these cases:
.map() renderingdata-fetching-strategist with page-based navDelegate instead:
data-table-architect skillreal-time-sync-engineer skillaccessibility-specialist skillmobile-performance-optimizer skilldata-ai
license: Apache-2.0 NOT for unrelated tasks outside this domain.
development
Use when designing caching strategies (cache-aside, write-through, write-behind), implementing distributed locks, building rate limiters, leaderboards, real-time streams (XADD/consumer groups), pub/sub, or tuning eviction policies. Triggers: thundering-herd on cache miss, dogpile on key expiry, Redlock vs SET-NX-PX choice, sliding-window rate limiter, hot-key on a single cluster slot, big-key blowup, MULTI/EXEC across slots, KEYS in production. NOT for Redis Cluster operations/admin (different domain), embedded KV (SQLite, leveldb), in-process LRU caches, or Memcached.
tools
Drawing the `'use client'` boundary correctly in React Server Components apps (Next.js App Router, RSC frameworks) — leaf-pushing, slot composition, serialization rules, and environment poisoning prevention. Grounded in react.dev and Next.js 16 docs.
development
Use when designing rate limiting for an API, choosing between token bucket / sliding window / leaky bucket / fixed window, implementing it in Redis, deciding edge (Cloudflare/Upstash) vs origin enforcement, sizing per-user vs per-IP vs per-endpoint quotas, returning the right 429 response with Retry-After, or fixing the boundary-burst bug in fixed-window limiters. Triggers: 429 too many requests, INCR + EXPIRE, ZADD + ZREMRANGEBYSCORE + ZCARD, X-RateLimit-Remaining header, Cloudflare WAF rate limiting rules, Upstash @upstash/ratelimit, leaky bucket shaping vs policing, distributed rate limiter consistency. NOT for DDoS mitigation specifically (different scale), CAPTCHA / bot management, full WAF design, or per-user quota billing.