You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

FullCalendar加载3k+任务卡顿问题优化方案求助

FullCalendar 3000条任务数据卡顿优化方案

1. 按需加载事件(核心优化)

不要一次性把所有任务传给FullCalendar,仅渲染当前视图范围内的事件:

  • 改用FullCalendar的events动态函数,在视图切换时自动过滤当前时间段的任务,避免全量渲染
  • 修改代码示例:
// 替换原有的calendarOptions.events赋值逻辑
calendarOptions: {
  //...其他原有配置
  events: (info, successCallback) => {
    // info.start/info.end为当前视图的起止时间
    const filteredTasks = this._tasks.filter(task => {
      const taskStart = new Date(task.date);
      const taskEnd = task.dueDate ? new Date(task.dueDate) : taskStart;
      // 判断任务与当前视图时间段是否有交集
      return taskEnd >= info.start && taskStart <= info.end;
    });
    // 仅转换过滤后的任务为FullCalendar事件格式
    const events = filteredTasks.map(task => {
      const startDate = formatDateTime(task.date);
      const endDate = task.dueDate ? formatDateTime(task.dueDate) : undefined;
      return {
        title: task.title,
        extendedProps: {
          eventId: task.serviceOrderId || task.documentId,
        },
        start: startDate,
        end: endDate,
        backgroundColor: this.getEventColor(task),
      };
    });
    successCallback(events);
  }
}
  • 移除原setTasks中直接赋值this.calendarOptions.events的逻辑,取消对_tasks的deep监听(改为仅监听数组引用变化)

2. 优化数据监听与转换性能

  • 去掉_tasks的deep: true监听:deep遍历3000条对象的开销极大,改为仅监听数组引用变化,任务更新时通过FullCalendar API刷新事件
// 修改watch配置
watch: {
  _tasks: {
    immediate: true,
    // 移除deep: true
    handler: function () {
      this.$refs.calendar.getApi().refetchEvents();
    },
  },
}
  • 缓存日期格式化和事件颜色计算结果:避免重复计算相同任务的日期与颜色
// 组件内添加缓存对象
data() {
  return {
    dateFormatCache: new Map(),
    eventColorCache: new Map()
  }
},
methods: {
  formatDateTimeCached(dateStr) {
    if (this.dateFormatCache.has(dateStr)) return this.dateFormatCache.get(dateStr);
    const formatted = formatDateTime(dateStr);
    this.dateFormatCache.set(dateStr, formatted);
    return formatted;
  },
  getEventColorCached(task) {
    const taskKey = task.serviceOrderId || task.documentId;
    if (this.eventColorCache.has(taskKey)) return this.eventColorCache.get(taskKey);
    const color = this.getEventColor(task);
    this.eventColorCache.set(taskKey, color);
    return color;
  }
}
// 事件转换时替换为缓存方法
const startDate = this.formatDateTimeCached(task.date);
const endDate = task.dueDate ? this.formatDateTimeCached(task.dueDate) : undefined;
backgroundColor: this.getEventColorCached(task),

3. 减少DOM渲染压力

  • 开启单日事件数量限制:当单日事件过多时自动折叠,减少DOM节点数量
calendarOptions: {
  //...其他配置
  eventLimit: true, // 开启折叠
  eventLimitText: '更多', // 自定义折叠提示文本
}
  • 简化自定义事件模板:避免复杂HTML结构或嵌套组件,降低渲染开销

4. 防抖处理视图更新

  • 对事件刷新操作添加防抖,避免快速切换月份时多次触发全量计算
// 引入防抖函数(或自行实现)
import { debounce } from 'lodash';

created() {
  this.debouncedRefetch = debounce(() => {
    this.$refs.calendar.getApi().refetchEvents();
  }, 150);
},
watch: {
  _tasks: {
    immediate: true,
    handler: function () {
      this.debouncedRefetch();
    },
  },
}

5. 降低响应式追踪开销

  • 如果_tasks仅作为展示数据、无需在组件内修改,可转为非响应式对象,减少Vue的响应式监听开销
methods: {
  // 在需要处理任务数据时使用
  getNonReactiveTasks() {
    // 通过JSON序列化断开响应式关联
    return JSON.parse(JSON.stringify(this._tasks));
  }
}

内容的提问来源于stack exchange,提问作者user16200753

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 11:07:06