After running a profile I figured where does performance degradation come from. Recently we changed Model code to deep clone incoming data. In our demos we use simple objects for events so it doesn't make a difference. But in your dataset event object is huge and has nested fields, so deep cloning it takes significant time.
Good news is that you can modify that behavior with a config. For example, enabling this brings performance to the same level as we saw in profiles that were taking above:
new Scheduler({
eventStore : {
useRawData : true
}
})
I updated the config as mentioned, I do see the performance improvement from 1700milliseconds(refer screenshot attached in prev comment) to 1300milliseconds(attaching the screenshot with this post). Tried this with 4.2.5 version.
But I still see the numbers not matching or better from 3.1.9 version which is 950milliseconds(Attaching the screenshot with this post)
As mentioned earlier this is one instance or area where I see the performance issue, the other area is after the events are added there is delay of events being displayed on the scheduler.
const scheduler = new Scheduler({
appendTo : 'container',
minHeight : '20em',
startDate : new Date(2021, 0, 1),
endDate : new Date(2021, 1, 1),
viewPreset : 'hourAndDay',
rowHeight : 50,
barMargin : 5,
multiEventSelect : true,
resourceStore : {
tree : true,
data : resources // resources from your archive
},
eventStore : {
useRawData : true
},
features : {
tree : true
},
columns : [
{ type : 'tree', text : 'Name', field : 'name', width : 130 }
]
});
const newEvents = [];
function getRandomInt(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min) + min);
}
for (let i = 0; i < 4000; i++) {
newEvents.push({
id : i,
resourceId : 'r' + getRandomInt(1, 11),
name : 'Team scrum ',
startDate : DateHelper.add(scheduler.startDate, i, 'h'),
endDate : DateHelper.add(scheduler.startDate, i + 1, 'h'),
location : 'Some office',
eventType : 'Meeting',
eventColor : '#ff0000',
iconCls : 'b-fa b-fa-users'
});
}
let t0, t1;
t0 = performance.now();
scheduler.eventStore.add(events); // events from your archive
t1 = performance.now();
console.log(`Call to eventStore.add took ${t1 - t0} milliseconds.`);
t0 = performance.now();
scheduler.eventStore.add(newEvents);
t1 = performance.now();
console.log(`Call to eventStore.add took ${t1 - t0} milliseconds.`);
This snippet logs
// 3.1.9
Call to eventStore.add took 171.39999985694885 milliseconds.
Call to eventStore.add took 51.39999985694885 milliseconds.
// latest nightly
Call to eventStore.add took 154 milliseconds.
Call to eventStore.add took 110.09999990463257 milliseconds
As you see, your data is loaded faster to the empty store. Next 4k dummy events are loaded slower to the filled store although time is proportional to the larger dataset (154 / 5200 * 4000 > 110).
I see that 4.2.4 takes 1.5 times more time to load events on your end, which we don't see locally. It might be related to store features enabled, or store listeners or smth else.
This is why we are asking for a runnable test case - it is likely we use different approach and will not see the same problem. I understand it might be problematic to create a runnable test case especially for large application. We can try simpler steps for now, for example examining your app configuration. We can try replicating it locally to check if it affects performance. We could also benefit from a recorded profile of the page, if it contains original method names from our bundle (best would be to have two, for 3.1.9 and 4.2.4)
On your end you can try disabling extra features/listeners to see if some of them affect performance significantly.
As mentioned above we did try removing the listeners, working hours from the scheduler and measuring the performance, not much improvement the result was around 1000milliseconds.
Also instead of our existing event object we tried the dummy event object from the previous code comment, we did notice the same result i.e around 1200milliseconds for 5k events.
Other observation was assigning the event to the respective resource is taking time, once by mistake we had added duplicate key "id" we were able to repro the performance issue in your examples set also. Not sure if this helps.
Getting the runnable test case is bit tricky as of now, sending you the profile and config which we are using.
UMD bundle doesn't use modern JS API and uses polyfills/transpilation to be compliant with ecmascript5. It is likely performance degradation is caused by them, we will check what we can do about that.
Workaround would be to switch to modules bundle, it uses modern JS syntax and, according to my measurements, it works a bit faster loading your data than older 3.1.9 edition. If you do not support IE11, transition should be fairly easy - it should be enough to replace the bundle and change imports.
As I mentioned above umd bundle for Scheduler would be less preferable than existing module one in terms of performance.
This happens because umd was built with ie11 target preset.
We will remove ie11 support in coming releases, stay tuned to updates notifications.
For now the solutions is to switch to scheduler.module.js bundle or create less "heavy" umd bundle for modern browsers with webpack.
I did take the transpiled code from scheduler.module as mentioned above, but am getting some error like "constructor not able to call without new method for " DraggerHelper.
Below is the sample code which am using
class Drag extends window.bryntum.scheduler.DragHelper {
static get defaultConfig() {
return {
// Don't drag the actual row element, clone it
cloneTarget: true,
mode: 'translateXY',
dropTargetSelector: ['.b-sch-timeaxis-cell', '.b-sch-style-plain'],
// Only allow drag of row elements inside on the unplanned grid
// targetSelector: '.b-grid-row',
targetSelector: '.rt-tr-group',
};
}
construct(config) {
const me = this;
super.construct(config);
me.on({
drag: me.onTaskDrag,
dragstart: me.onTaskDragStart,
drop: me.onTaskDrop,
thisObj: me,
});
}
}
The above error was due to classes were not being transformed, after fixing we did take the umd bundle generated from module bundle, also we are using the config
eventStore:{useRawData: true}
.
Unfortunately we don't see any improvements in the numbers. We are still seeing it to be around 1665.0999999940395 milliseconds for 5k events.
Once again attaching the profile if it might help you any further.