0

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

MiChAeLoKGB
  • 796
  • 14
  • 38
  • maybe ask yourself if this is the best UI. Would you be better with fullCalendar's Scheduler plugin (one for for each employee?). Obviously you'd have to pay for it unless your client is a non-profit organisation. Or you could maybe have one calendar widget, with events for different employees shown in different colours? – ADyson Aug 02 '17 at 10:26
  • @ADyson IMO, its less cluttered and you can just drag and drop those widgets and organize them as you want. We don't need the Scheduler plugin. Its not for scheduling, but for looking at what people on your team have in their calendar and maybe even add them something new (if you have the rights to do so). Right now we are jut thinking about making it reload whole page, as its quite a lot faster than using ajax... – MiChAeLoKGB Aug 02 '17 at 14:47
  • "what people on your team have in their calendar" _is_ scheduling. In this case the people can be considered as the "resources". A Schedule (in fullCalendar's meaning) is just a calendar where you can see multiple streams of events in one view. It fits the model of multiple people's calendars perfectly, IMHO. But it's a paid plugin, so that's not ideal. Perhaps there are other similar free widgets around online. I say this because I strongly suspect your performance issues are due to the number of calendars running scripts (and also the number of ajax calls being made) – ADyson Aug 05 '17 at 09:55
  • Thanks for explanation. Maybe it is for some, but for us it **has** to be in multiple calendars (as they still are widgets and you can re-order them however you want). Also, some calendars are quite full, so you could have a day with hundreds of events, which is also not good. And the ajax calls aren't the issue as I said in my question, I did change how we load the events and its a single ajax call for all calendars and results are cached. The issue is about 200 - 300 ms it takes for FullCalendar to redraw (now 250 x 15 and R.I.P.). Its funny, but just reloading the page is actually faster :D – MiChAeLoKGB Aug 06 '17 at 10:08
  • when you draw the calendar there's obviously quite a lot to do in terms of adding new elements and removing old ones, esp. if some calendars have got hundreds of events in them. So yes I'd expect it to take a bit of time. If, as you seem to have done, you can quantify a time of 250ms extra per calendar that you add to the page, then that would seem to be the minimum time it will take to render. Not a lot you can do about that short of trying to optimise the fullCalendar source code. – ADyson Aug 07 '17 at 21:28
  • Have you got a "loading" indicator that will show when this re-rendering is happening? Users are often happy to wait for a second or two if they can see something moving which tells them there's a change coming up. More so now that ajax is so common in websites, and waiting times for that can vary immensely depending on network speed etc. – ADyson Aug 07 '17 at 21:29
  • Just to close this off for anybody with same problem: today I re-worked it to PHP and even if it has to reload the whole website every time, now it takes about 0,5 - 1 second to load everything, when before it took over 2 seconds using ajax. The main slowdown was whole repaint of fullcalendar (its even rebinding all buttons every single time, wtf?) and lack of some methods I needed (that caused the need to reload all calendars twice). – MiChAeLoKGB Sep 13 '17 at 15:22

0 Answers0