<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Oluwatomisin Oyemade</title>
    <description>The latest articles on DEV Community by Oluwatomisin Oyemade (@dev_tom).</description>
    <link>https://dev.to/dev_tom</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1344739%2F4fdb8c99-c3d6-4dae-b631-ac86f31e631c.png</url>
      <title>DEV Community: Oluwatomisin Oyemade</title>
      <link>https://dev.to/dev_tom</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/dev_tom"/>
    <language>en</language>
    <item>
      <title>Virtualisation with TanStack Virtual</title>
      <dc:creator>Oluwatomisin Oyemade</dc:creator>
      <pubDate>Tue, 17 Feb 2026 20:39:21 +0000</pubDate>
      <link>https://dev.to/dev_tom/virtualisation-with-tanstack-virtual-2md5</link>
      <guid>https://dev.to/dev_tom/virtualisation-with-tanstack-virtual-2md5</guid>
      <description>&lt;p&gt;Optimising performance is a common topic in the React community. Users expect smooth scrolling and quick interactions, especially when handling large datasets that can grow to thousands of entries.&lt;/p&gt;

&lt;p&gt;Virtualisation improves large lists by displaying only the visible elements (plus a small buffer) rather than loading thousands of DOM elements all at once. As the user scrolls, elements are added and removed dynamically, while the list maintains the appearance of a fully rendered dataset without any drop in performance.&lt;/p&gt;

&lt;p&gt;But why do we need Virtualisation?&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Why Virtualisation Is Essential&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;When handling extensive datasets:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Memory consumption: Rendering numerous DOM elements utilises a considerable amount of memory.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Initial rendering speed: The initial display slows down as React builds and reconciles a large tree.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Scrolling responsiveness: Working with large datasets increases the workload and DOM size, leading to sluggish scrolling.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;User experience: It might look as though the application is malfunctioning, even though it works properly, because of the slow response when scrolling and tapping.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Virtualisation significantly reduces DOM node count, often resulting in smoother scrolling and faster interactions. Various methods exist for implementing Virtualisation in React. In this piece, we’ll concentrate on &lt;strong&gt;TanStack Virtual&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Introduction to TanStack Virtual&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;TanStack Virtual is a headless virtualisation library. It does not include prebuilt UI components. Instead, it provides the virtualisation &lt;strong&gt;engine&lt;/strong&gt; (including ranges, offsets, total size, and measurement utilities), allowing you to maintain complete control over your markup, styling, layout, and interactions. This offers a significant benefit when your list items are not just basic rows but also intricate UI elements such as badges, menus, images, buttons, and complex designs.&lt;/p&gt;

&lt;p&gt;Let’s get it set up in your project.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Installation&lt;/strong&gt;
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install @tanstack/react-virtual
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn add @tanstack/react-virtual
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pnpm add @tanstack/react-virtual
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;Understanding TanStack Virtual Fundamentals&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;TanStack Virtual isn’t a UI component library you drop into your app and forget about. It’s a lightweight utility that handles the hard part of Virtualisation, determining:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;which items should be visible,&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;where those items should be positioned in the scroll space,&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;and how large the full list should appear (so the scrollbar behaves naturally).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You still build the UI yourself: your markup, styling, layout, and interactions.&lt;/p&gt;

&lt;p&gt;Now, let's analyse it step by step.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Mental model (the “illusion”)&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;A virtual list usually has three pieces:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Scroll container – a div with a fixed height and overflow: auto&lt;/li&gt;
&lt;li&gt;Spacer – an inner element with the total list height (getTotalSize())&lt;/li&gt;
&lt;li&gt;Virtual items – only the visible items, positioned using transform: translateY(...)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { useVirtualizer } from "@tanstack/react-virtual";

export function BasicVirtualList() {
  const parentRef = React.useRef&amp;lt;HTMLDivElement | null&amp;gt;(null);

  const items = React.useMemo(
    () =&amp;gt; Array.from({ length: 100_000 }, (_, i) =&amp;gt; `Item ${i + 1}`),
    []
  );

  const virtualizer = useVirtualizer({
    count: items.length,
    getScrollElement: () =&amp;gt; parentRef.current,
    estimateSize: () =&amp;gt; 44, // fixed row height
    overscan: 8,
  });

  return (
    &amp;lt;div
      ref={parentRef}
      style={{
        height: 450,
        overflow: "auto",
        border: "1px solid #e5e7eb",
        borderRadius: 12,
      }}
    &amp;gt;
      &amp;lt;div
        style={{
          height: virtualizer.getTotalSize(),
          position: "relative",
        }}
      &amp;gt;
        {virtualizer.getVirtualItems().map((vItem) =&amp;gt; (
          &amp;lt;div
            key={vItem.key}
            style={{
              position: "absolute",
              top: 0,
              left: 0,
              width: "100%",
              height: vItem.size,
              transform: `translateY(${vItem.start}px)`,
              display: "flex",
              alignItems: "center",
              padding: "0 12px",
              borderBottom: "1px solid #f3f4f6",
              boxSizing: "border-box",
            }}
          &amp;gt;
            {items[vItem.index]}
          &amp;lt;/div&amp;gt;
        ))}
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;Key Concepts You’ll Use in Every Implementation&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;estimateSize:&lt;/strong&gt; A function that returns an estimated item height (or width for horizontal lists).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;getItemKey:&lt;/strong&gt; Utilise consistent keys when your list might change (due to sorting, filtering, or new data coming in) to guarantee that virtualisation stays stable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;overscan:&lt;/strong&gt; Controls the number of extra items that render above and below the viewport. Higher overscan reduces blank gaps during fast scrolling, but increases work per scroll.&lt;/p&gt;

&lt;p&gt;Aside from configuration, practical factors can influence the effectiveness of virtualisation in your application.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Tips for Virtualisation&lt;/strong&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Fixed vs variable item height: Using a fixed layout is usually more straightforward, while a variable one means you’ll need to measure and manage sizes carefully.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Row state: Virtualised rows may mount and unmount as you scroll. Make sure any critical data or state isn’t stored only inside the row components themselves.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Focus &amp;amp; accessibility: When a row is unmounted, input and keyboard navigation may break if focus disappears.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Images and dynamic content: Media that loads slowly can change heights, which can cause scroll jumps if not treated carefully.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Performance proof: Check the results before and after using the React Profiler and Chrome Performance tools.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Common Pitfalls (And How to Avoid Them)&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Even when following best practices, virtualised lists can introduce subtle bugs and performance issues. Here are some common issues and their solutions.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Blank gaps during rapid scrolling: Increase the &lt;code&gt;overscan&lt;/code&gt; slightly so that more items are rendered beyond the visible viewport.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Scroll jumps with variable content: Reserve space for images by setting a fixed height or aspect ratio, or allow accurate measurement to prevent scroll position shifts due to dynamic height changes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Losing row state: Lift the state and store it by id. Avoid keeping crucial state solely inside row components, as they may mount and unmount during scrolling.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Wrong keys: Use stable keys with &lt;code&gt;getItemKey&lt;/code&gt; when the list order might change. Do not rely on array indices&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Wrap Up&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Virtualisation is among the most effective performance improvements you can implement for extensive lists in React. With TanStack React Virtual, you receive a versatile, headless engine that integrates smoothly into actual applications—particularly when you desire complete control over the UI layout.&lt;/p&gt;

</description>
      <category>virtualisation</category>
      <category>tanstack</category>
      <category>webdev</category>
      <category>react</category>
    </item>
  </channel>
</rss>
