---
title: "Vue Scheduler Large Dataset Performance Example | Mobiscroll"
component: "Scheduler"
framework: "Vue"
library_version: "6.1.5"
url: "https://demo.mobiscroll.com/vue/scheduler/loading-big-data-sets"
---

# Large Dataset Performance - Vue Scheduler demo

See how the Vue Scheduler handles large data sets— virtual scrolling keeps 20 resources and 2,000 events smooth on mobile and desktop. For Vue and Nuxt.

- [Live demo](https://demo.mobiscroll.com/vue/scheduler/loading-big-data-sets)
- [View SFC JS code on GitHub](https://github.com/acidb/mobiscroll-demos-vue/tree/main/src/demos/eventcalendar/scheduler/loading-big-data-sets)
- [View SFC TS code on GitHub](https://github.com/acidb/mobiscroll-demos-vue-ts/tree/main/src/demos/eventcalendar/scheduler/loading-big-data-sets)
- This demo in other frameworks: [JavaScript](https://demo.mobiscroll.com/javascript/scheduler/loading-big-data-sets.md), [jQuery](https://demo.mobiscroll.com/jquery/scheduler/loading-big-data-sets.md), [Angular](https://demo.mobiscroll.com/angular/scheduler/loading-big-data-sets.md), [React](https://demo.mobiscroll.com/react/scheduler/loading-big-data-sets.md)

## Description

The scheduler supports virtual horizontal and vertical scrolling. The view virtualization makes it possible to work with many resources across long date ranges.

The following examples shows that navigating 20 resources across a whole month with 2000 events won't pose any problems for the browser neither on mobile or desktop.

View virtualization is always enabled and doesn't need to be turned on explicitly.

## What this demo shows

- A desktop monthly scheduler layout with a fixed month strip at the top, repeated resources for each day, a fixed all-day row below it, and a scrollable scheduler time grid for the selected month.
- **Virtual scroll** The scheduler supports virtual horizontal and vertical scrolling. The view virtualization makes it possible to work with many resources across long date ranges.
- **Header navigation** The month and year label in the top left opens date navigation, while the blue previous and next arrows and the Today button on the right make it easy to move between weeks and jump back to the current day.
- **Week view** The fixed strip below the header displays the days of the selected month, with the current date highlighted by a blue circle.
- **Resources**: Each day repeats the same 20 resources.
- **All-day events** All-day events appear in a dedicated row that stays fixed above the time grid.
- **Time grid** The scheduler grid scrolls vertically through the hours of the selected month.
- **Timed events** Timed events are displayed in the monthly scheduler grid as colored cards with a colored stripe on the left, the event title in bold, and the exact start and end time displayed above the title.
- **Event overlapping** If events overlap, the scheduler places them side by side without hiding any of them or causing other conflicts.
- **Current time** A blue current-time line appears across the time grid.
- **Event interaction** Hovering over events highlights them and shows drag and resize handles for repositioning or changing duration.
- **Event selection** Clicking an event selects and highlights it.
- **Event creation** Double-clicking the time grid or clicking and dragging on it creates a new event.

## Best for

- **Virtual scrolling** Demonstrating how horizontal and vertical virtual scroll works with the scheduler.

## API used in this demo

- [`theme`](https://mobiscroll.com/docs/vue/eventcalendar/api#opt-theme) - option
- [`themeVariant`](https://mobiscroll.com/docs/vue/eventcalendar/api#opt-themeVariant) - option
- [`clickToCreate`](https://mobiscroll.com/docs/vue/eventcalendar/api#opt-clickToCreate) - option
- [`dragToCreate`](https://mobiscroll.com/docs/vue/eventcalendar/api#opt-dragToCreate) - option
- [`dragToMove`](https://mobiscroll.com/docs/vue/eventcalendar/api#opt-dragToMove) - option
- [`dragToResize`](https://mobiscroll.com/docs/vue/eventcalendar/api#opt-dragToResize) - option
- [`eventDelete`](https://mobiscroll.com/docs/vue/eventcalendar/api#opt-eventDelete) - option
- [`view`](https://mobiscroll.com/docs/vue/eventcalendar/api#opt-view) - option
- [`data`](https://mobiscroll.com/docs/vue/eventcalendar/api#opt-data) - option
- [`resources`](https://mobiscroll.com/docs/vue/eventcalendar/api#opt-resources) - option
- [`groupBy`](https://mobiscroll.com/docs/vue/eventcalendar/api#opt-groupBy) - option
- [`page-loading`](https://mobiscroll.com/docs/vue/eventcalendar/api#event-onPageLoading) - event

## Code

### SFC JS

```vue
<script setup>
import { MbscEventcalendar, setOptions } from '@mobiscroll/vue'
import { ref } from 'vue'

setOptions({
  theme: 'ios',
  themeVariant: 'light'
})

const myEvents = ref([])

const myView = {
  scheduler: {
    type: 'month',
    timeCellStep: 15,
    timeLabelStep: 15
  }
}

const resourceNr = 20
const eventsNr = 2000
const myResources = []
const myEventColors = ['#ff0101', '#239a21', '#8f1ed6', '#01adff', '#d8ca1a']

for (let i = 1; i <= resourceNr; i++) {
  myResources.push({ name: 'Resource ' + i, id: i })
}

function getRandomInt(min, max) {
  return Math.floor(Math.random() * (max - min) + min)
}

function handlePageLoading(args) {
  setTimeout(() => {
    const newEvents = []
    const year = args.firstDay.getFullYear()
    const month = args.firstDay.getMonth()
    const daysInMonth = new Date(year, month + 1, 0).getDate()
    // Generate random events for the visible month
    for (let i = 0; i < eventsNr; i++) {
      const day = getRandomInt(1, daysInMonth + 1)
      const resource = getRandomInt(1, resourceNr + 1)
      const color = getRandomInt(0, myEventColors.length)
      const startHour = getRandomInt(0, 23)
      const startMinute = getRandomInt(0, 4) * 15
      const start = new Date(year, month, day, startHour, startMinute)
      const end = new Date(start.getTime() + getRandomInt(2, 9) * 15 * 60 * 1000)
      if (end.getDate() === start.getDate()) {
        newEvents.push({
          color: myEventColors[color],
          end: end,
          resource: resource,
          start: start,
          title: 'Event ' + i
        })
      }
    }
    myEvents.value = newEvents
  })
}
</script>

<template>
  <MbscEventcalendar :clickToCreate="true" :dragToCreate="true" :dragToMove="true" :dragToResize="true" :eventDelete="true"
    :view="myView"
    :data="myEvents"
    :resources="myResources"
    groupBy="date"
    @page-loading="handlePageLoading"
  />
</template>

<style>
/* code */
</style>
```

### SFC TS

```vue
<script setup lang="ts">
import { MbscEventcalendar, setOptions } from '@mobiscroll/vue'
import type {
  MbscCalendarEvent,
  MbscEventcalendarView,
  MbscPageLoadingEvent,
  MbscResource
} from '@mobiscroll/vue'
import { ref } from 'vue'

setOptions({
  theme: 'ios',
  themeVariant: 'light'
})

const myEvents = ref<MbscCalendarEvent[]>([])

const myView: MbscEventcalendarView = {
  scheduler: {
    type: 'month',
    timeCellStep: 15,
    timeLabelStep: 15
  }
}

const resourceNr: number = 20
const eventsNr: number = 2000
const myResources: MbscResource[] = []
const myEventColors: any = ['#ff0101', '#239a21', '#8f1ed6', '#01adff', '#d8ca1a']

for (let i = 1; i <= resourceNr; i++) {
  myResources.push({ name: 'Resource ' + i, id: i })
}

function getRandomInt(min: number, max: number) {
  return Math.floor(Math.random() * (max - min) + min)
}

function handlePageLoading(args: MbscPageLoadingEvent) {
  setTimeout(() => {
    const newEvents: MbscCalendarEvent[] = []
    const year = args.firstDay.getFullYear()
    const month = args.firstDay.getMonth()
    const daysInMonth = new Date(year, month + 1, 0).getDate()
    // Generate random events for the visible month
    for (let i = 0; i < eventsNr; i++) {
      const day = getRandomInt(1, daysInMonth + 1)
      const resource = getRandomInt(1, resourceNr + 1)
      const color = getRandomInt(0, myEventColors.length)
      const startHour = getRandomInt(0, 23)
      const startMinute = getRandomInt(0, 4) * 15
      const start = new Date(year, month, day, startHour, startMinute)
      const end = new Date(start.getTime() + getRandomInt(2, 9) * 15 * 60 * 1000)
      if (end.getDate() === start.getDate()) {
        newEvents.push({
          color: myEventColors[color],
          end: end,
          resource: resource,
          start: start,
          title: 'Event ' + i
        })
      }
    }
    myEvents.value = newEvents
  })
}
</script>

<template>
  <MbscEventcalendar :clickToCreate="true" :dragToCreate="true" :dragToMove="true" :dragToResize="true" :eventDelete="true"
    :view="myView"
    :data="myEvents"
    :resources="myResources"
    groupBy="date"
    @page-loading="handlePageLoading"
  />
</template>

<style>
/* code */
</style>
```

## Implementation notes

- Use `view: { scheduler: { type: 'month', timeCellStep: 15, timeLabelStep: 15 } }` with `groupBy="date"` - a month view with 15-minute cells and date-grouped columns (rows = resources, columns = days).
- Programmatically generate 20 resources at module level.
- **`onPageLoading` handler** (Vue: `@page-loading`): generates 2,000 random events for the currently visible month on every page navigation.
  1. Extract `year` and `month` from `args.firstDay.getFullYear()` / `args.firstDay.getMonth()`.
  2. Wrap the generation loop in `setTimeout` (no delay) to defer heavy computation off the current render cycle.
  3. For each event, pick a random `day`, `resource`, `color`, `startHour`, and `startMinute` (multiples of 15), then compute `end` as 2-8 × 15-minute blocks after `start`. Skip any event whose end crosses midnight - all generated events stay within a single day.
  4. After the loop, update the events; for the imperative API, call `inst.setEvents(myEvents)`.

## Run it in your project

1. If not signed up yet, or don't own a license, you can [start a free trial](https://mobiscroll.com/starttrial).

2. Clone the repository:

   ```
   git clone https://github.com/acidb/mobiscroll-demos-vue.git
   ```

3. If not installed yet, install the Mobiscroll CLI from NPM:

   ```
   npm install -g @mobiscroll/cli
   ```

4. Config Mobiscroll - open a terminal window in the root directory and run:

   ```
   mobiscroll config vue
   ```

5. Install dependencies - open a terminal window in the root directory and run:

   ```
   npm install
   ```

6. Run the project:

   ```
   npm run dev
   ```

On a trial, add `--trial` to the config command: `mobiscroll config vue --trial`.

Running a demo locally requires a Mobiscroll trial or a license; setup is per framework at https://mobiscroll.com/docs/vue/getting-started/installation

## Related demos

- Previous: [Lazy Load Events on Scroll](https://demo.mobiscroll.com/vue/scheduler/load-events-on-scroll.md) - Load Vue scheduler events on demand as users scroll — fetch only the visible date range to keep performance fast with large event counts.
