I have a dashboard, where people can put multiple fullcalendar widgets (imagine a team dashboard with a fullcalendar widget for every person in a team). The main issue with this is performance. One client has 16 such widgets (all quite full of events) and they are not limited in number.
Only the first calendar has header controls (others have them hidden using CSS).
What I need is to propagate the changes to view (switch basicWeek
to month
etc.), firstDay
(today in basicWeek
, Monday everywhere else) and the date (prev
, next
, today
) from first calendar to other calendars.
The issue is performance. As I didn't really find a way how to do it (that wouldn't look really hacky) except in viewRender
, which is called for every single change. That means, if you switch from basicWeek
to agendaWeek
the first calendar propagates the firstDay
to other calendars (which calls viewRender
) and after that propagates the view change, which basically re-renders all calendars (except the first one) twice.
Is there a way to propagate those changes and manually call render on other calendars (from what I see in the source code, there might not be one), or a better way to do it? I am also thinking about just destroying the calendars and re-initializing them with new options, but that might cause flashing (instead of quite a lot of lag caused by multiple re-renders). One of the options I thought of was using my own buttons (or re-using default buttons just unbinding original events from them), but even then I would still have to re-render the calendars multiple times in some occasions.
Switching view with 6 almost empty calendars takes about 3 seconds, which is unacceptable.
This is how my viewRender
code looks like (this is inside own fullcalendar function, so every widget has its own scope with cached variables and settings)
viewRender: function(view) {
console.log('viewRender', calendarid, lastView, view.type);
// Propagate all changes from first calendar to other calendars on the page
if ($('#' + calendarid).parents('.widgetCalendar').is(':first-child')) {
// Change the first day (basicWeek is always today, other views are always Monday)
if (view.type != 'basicWeek' && currFirstDay != 1) {
currFirstDay = 1;
$('.calendarDiv').fullCalendar('option', 'firstDay', 1);
return;
} else if (view.type == 'basicWeek' && currFirstDay != firstday) {
currFirstDay = firstday;
$('.calendarDiv').fullCalendar('option', 'firstDay', firstday);
return;
}
// Propagate the view change to other calendars
if (lastView != view.type) {
lastView = view.type;
$('.calendarDiv:not(#' + calendarid + ')').fullCalendar('changeView', view.type); // , view.intervalStart.valueOf());
}
// Propagate the date change to other calendars
if (lastDate != view.intervalStart.valueOf()) {
lastDate = view.intervalStart.valueOf();
$('.calendarDiv:not(#' + calendarid + ')').fullCalendar('gotoDate', view.intervalStart.valueOf());
}
}
},
Ps.: At first I thought this issue is mainly ajax requests to get new events, but I changed that to a function which uses single call and caches the results. The main reason I thought that were some delays between ajax and that they weren't concurrent (session locking). But changing it to new function shows that the issue are indeed the re-renders which take white a long time per calendar (about 250 - 350ms).
If there is any info missing, ask in the comments and I will update the question.
Fullcalendar version: 3.4.0