Need help with vue-virtual-scroller?
Click the “chat” button below for chat support from the developer who created it, or find similar developers for support.

About the developer

6.2K Stars 563 Forks 259 Commits 170 Opened issues


⚡️ Blazing fast scrolling for any amount of data

Services available


Need anything else?

Contributors list


npm npm vue2

Blazing fast scrolling of any amount of data | Live demo | Video demo

For Vue 3 support, see here

💚️ Become a Sponsor


sponsors logos

Table of contents


npm install --save vue-virtual-scroller


now uses vue-observe-visibility to automatically refresh itself when shown to prevent display glitches. This means you need to include the Intersection Observer polyfill needed by
for this to work in old browsers (like Internet Explorer).

Default import

Install all the components:

import Vue from 'vue'
import VueVirtualScroller from 'vue-virtual-scroller'


Use specific components:

import Vue from 'vue'
import { RecycleScroller } from 'vue-virtual-scroller'

Vue.component('RecycleScroller', RecycleScroller)

⚠️ The line below should be included when importing the package:

import 'vue-virtual-scroller/dist/vue-virtual-scroller.css'


If Vue is detected, the plugin will be installed automatically. If not, install the component:


Or register it with a custom name:

Vue.component('RecycleScroller', VueVirtualScroller.RecycleScroller)


There are several components provided by


RecycleScroller is a component that only renders the visible items in your list. It also re-uses components and dom elements to be as efficient and performant as possible.

DynamicScroller is a component that wraps the RecycleScroller component and extends its features to include dynamic size management. The main use case for this is when you do not know the size of the items in advance. The Dynamic Scroller automatically "discovers" item dimensions as it renders new items during scrolling.

DynamicScrollerItem must wrap each item in a DynamicScroller to handle size computations.

IdState is a mixin that ease the local state management in reused components inside a RecycleScroller.


RecycleScroller is a virtual scroller that only renders the visible items. As the user scrolls, RecycleScroller reuses all components and DOM nodes to maintain optimal performance.

Basic usage

Use the scoped slot to render each item in the list:

Important notes

  • ⚠️ You need to set the size of the virtual-scroller element and the items elements (for example, with CSS). Unless you are using variable size mode, all items should have the same height (or width in horizontal mode) to prevent display glitches.
  • ⚠️ If the items are objects, the scroller needs to be able to identify them. By default it will look for an
    field on the items. This can be configured with the
    prop if you are using another field name.
  • It is not recommended to use functional components inside RecycleScroller since the components are reused (so it will actually be slower).
  • The list item components must be reactive to the
    prop being updated without being re-created (use computed props or watchers to properly react to props changes!).
  • You don't need to set
    on list content (but you should on all nested
    elements to prevent load glitches).
  • The browsers have a size limitation on DOM elements, it means that currently the virtual scroller can't display more than ~500k items depending on the browser.
  • Since DOM elements are reused for items, it's recommended to define hover styles using the provided
    class instead of the
    state selector (e.g.
    .hover .some-element-inside-the-item-view

How does it work?

  • The RecycleScroller creates pools of views to render visible items to the user.
  • A view holds a rendered item, and is reused inside its pool.
  • For each type of item, a new pool is created so that the same components (and DOM trees) are reused for the same type.
  • Views can be deactivated if they go off-screen, and can be reused anytime for a newly visible item.

Here is what the internals of RecycleScroller look like in vertical mode:


When the user scrolls inside RecycleScroller, the views are mostly just moved around to fill the new visible space, and the default slot properties updated. That way we get the minimum amount of components/elements creation and destruction and we use the full power of Vue virtual-dom diff algorithm to optimize DOM operations!


  • items
    : list of items you want to display in the scroller.
  • direction
    ): scrolling direction, either
  • itemSize
    ): display height (or width in horizontal mode) of the items in pixels used to calculate the scroll size and position. If it is set to
    (the default value), it will use variable size mode.
  • minItemSize
    : minimum size used if the height (or width in horizontal mode) of a item is unknown.
  • sizeField
    ): field used to get the item's size in variable size mode.
  • typeField
    ): field used to differentiate different kinds of components in the list. For each distinct type, a pool of recycled items will be created.
  • keyField
    ): field used to identify items and optimize managing rendered views.
  • pageMode
    ): enable Page mode.
  • prerender
    ): render a fixed number of items for Server-Side Rendering (SSR).
  • buffer
    ): amount of pixel to add to edges of the scrolling visible area to start rendering items further away.
  • emitUpdate
    ): emit a
    event each time the virtual scroller content is updated (can impact performance).


  • resize
    : emitted when the size of the scroller changes.
  • visible
    : emitted when the scroller considers itself to be visible in the page.
  • hidden
    : emitted when the scroller is hidden in the page.
  • update (startIndex, endIndex)
    : emitted each time the views are updated, only if
    prop is

Default scoped slot props

  • item
    : item being rendered in a view.
  • index
    : reflects each item's position in the
  • active
    : whether or not the view is active. An active view is considered visible and being positioned by
    . An inactive view is not considered visible and is hidden from the user. Any rendering-related computations should be skipped if the view is inactive.

Other Slots




Page mode

The page mode expands the virtual-scroller and uses the page viewport to compute which items are visible. That way, you can use it in a big page with HTML elements before or after (like a header and a footer). Set the

prop to
Copyright 2017 - Cat

Variable size mode

⚠️ This mode can be performance heavy with a lot of items. Use with caution.

If the

prop is not set or is set to
, the virtual scroller will switch to variable size mode. You then need to expose a number field on the item objects with the size of the item element.

⚠️ You still need to set the size of the items with CSS correctly (with classes for example).

Use the

prop (default is
) to set the field used by the scroller to get the size for each item.


const items = [
    id: 1,
    label: 'Title',
    size: 64,
    id: 2,
    label: 'Foo',
    size: 32,
    id: 3,
    label: 'Bar',
    size: 32,


You can set the

prop (in pixels) on the virtual-scroller to extend the viewport considered when determining the visible items. For example, if you set a buffer of 1000 pixels, the virtual-scroller will start rendering items that are 1000 pixels below the bottom of the scroller visible area, and will keep the items that are 1000 pixels above the top of the visible area.

The default value is


Server-Side Rendering


props can be set as the number of items to render on the server inside the virtual scroller:


This works just like the RecycleScroller, but it can render items with unknown sizes!

Basic usage

Important notes

  • minItemSize
    is required for the initial render of items.
  • DynamicScroller
    won't detect size changes on its own, but you can put values that can affect the item size with
    on DynamicScrollerItem.
  • You don't need to have a
    field on the items.


Extends all the RecycleScroller props.

  • It's not recommended to change
    prop since all the size management is done internally.


Extends all the RecycleScroller events.

Default scoped slot props

Extends all the RecycleScroller scoped slot props.

Other slots

Extends all the RecycleScroller other slots.


The component that should wrap all the items in a DynamicScroller.


  • item
    (required): the item rendered in the scroller.
  • active
    (required): is the holding view active in RecycleScroller. Will prevent unnecessary size recomputation.
  • sizeDependencies
    : values that can affect the size of the item. This prop will be watched and if one value changes, the size will be recomputed. Recommended instead of
  • watchData
    ): deeply watch
    for changes to re-calculate the size (not recommended, can impact performance).
  • tag
    ): element used to render the component.
  • emitResize
    ): emit the
    event each time the size is recomputed (can impact performance).


  • resize
    : emitted each time the size is recomputed, only if
    prop is


This is convenience mixin that can replace

in components being rendered in a RecycleScroller.

Why is this useful?

Since the components in RecycleScroller are reused, you can't directly use the Vue standard

properties: otherwise they will be shared with different items in the list!

IdState will instead provide an

object which is equivalent to
, but it's linked to a single item with its identifier (you can change which field with


In this example, we use the

of the
to have a "scoped" state to the item:


  • idProp
    vm =>
    ): field name on the component (for example:
    ) or function returning the id.



We use cookies. If you continue to browse the site, you agree to the use of cookies. For more information on our use of cookies please see our Privacy Policy.