Performance with 1000's + tasks

Hi!

I would like to know if someone has tried to load 1000’s of tasks in a gantt and what type of performance was found while scrolling up and down through the rows and horizontally through periods. Is there a cache mechanism in the background that only “load” and displays what’s required?

Thanks!

Gantt renders only tasks which are in the current time rang. So you can load task for 12 month, but show only one - gantt will render tasks only for that month.

As for rows - there is no dynamic rendering here, Gantt renders all rows at once. Default rendering logic is quite fast, so it must not be problem for medium-to-big datasets.

Hi!
I have performed some tests based on the samples supplied. My main goal is to determine how the gantt performs when scrolling horizontally/vertically when lots of tasks are displayed.

First example is based on 01-basic_init.html which I have modified to load 100 tasks spread over days.

<!DOCTYPE html>
<head>
	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
	<title>Basic initialization</title>
</head>
	<script src="../../sources/codebase/dhtmlxgantt.js" type="text/javascript" charset="utf-8"></script>
	<link rel="stylesheet" href="../../sources/codebase/dhtmlxgantt.css" type="text/css" media="screen" title="no title" charset="utf-8">

	<script type="text/javascript" src="../../common/testdata.js"></script>
	<style type="text/css">
		html, body{ height:100%; padding:0px; margin:0px; overflow: hidden;}
	</style>
<body>
	<div id="gantt_here" style='width:100%; height:100%;'></div>
	<script type="text/javascript">
     /*   var tasks =  {
            data:[
               {id:1, text:"Project #2", start_date:"01-04-2013", duration:18,order:10,
                    progress:0.4, open: true},
                {id:2, text:"Task #1", 	  start_date:"02-04-2013", duration:8, order:10,
                    progress:0.6, parent:1},
                {id:3, text:"Task #2",    start_date:"11-04-2013", duration:8, order:20,
                    progress:0.6, parent:1}
            ],
                    links:[
            { id:1, source:1, target:2, type:"1"},
            { id:2, source:2, target:3, type:"0"},
            { id:3, source:3, target:4, type:"0"},
            { id:4, source:2, target:5, type:"2"},
        ]
        };*/
        
        function GetFormattedDate(d) {
var todayTime = d;

var month = todayTime.getMonth() + 1;

var day = todayTime.getDate();

var year = todayTime.getFullYear();

return day + "-" + month + "-" + year;

}

        var tasks = {
                            data: [],
                            links: []
                          };
                          var date = new Date('02-04-2013');
                          tasks.data.push({
                                id:  1,
                                start_date: GetFormattedDate(date),
                                text: "Project1",
                                open:true
                             });
                            for (var i = 1; i < 100; i++) {
                              date.setDate(date.getDate() + 1);
                              tasks.data.push({
                                id: i + 1,
                                start_date: GetFormattedDate(date),
                                text: "Task " + (i + 1),
                                duration: 8,
                                parent:1
                              });
                            }  
                            
		gantt.init("gantt_here");


		gantt.parse(tasks);

	</script>

This performs pretty well. Even expanding the node Project 1 was pretty quick.

Based on this I have tried to increase tasks to 1000 even 10000. With 1000 it eventually loaded but was quite slow to scroll, for 10000 it took too long and I killed it. Very slow expanding Project 1 too.

Second example;

        var tasks = {
                            data: [],
                            links: []
                          };
                          var date = new Date('02-04-2013');
                          tasks.data.push({
                                id:  1,
                                start_date: GetFormattedDate(date),
                                text: "Project1",
                                open:true
                             });
                            for (var i = 1; i < 100; i++) {
                              date.setDate(date.getDate() + 1);
                              tasks.data.push({
                                id: i + 1,
                                start_date: GetFormattedDate(date),
                                text: "Task " + (i + 1),
                                duration: 8,
                                parent:1
                              });
                            } 
                            tasks.data.push({
                                id: 101,
                                start_date: GetFormattedDate(date),
                                text: "Project2",
                                open:true
                             });
                            for (var i = 1; i < 100; i++) {
                              date.setMonth(date.getMonth() + 1);
                              tasks.data.push({
                                id: i + 101,
                                start_date: GetFormattedDate(date),
                                text: "Task " + (i + 101),
                                duration: 8,
                                parent:101
                              });
                            }

this time I added Project 2 node with another 100 tasks this time spread over months. Result was pretty bad as browser did not even respond after loading.

In those two examples I have not included any dependencies and I would expect lower performance with more things drawn on screen.

Performance is key for our project, maybe there is a better way to create the tasks and send them to the gantt, please advise.

Hello,
the performance issue is mostly caused by a big number of cell elements. Number of elements (and, accordingly, the time required for rendering) grows as
((scale.end_date - scale.start_date) / scaleUnit) * numberOfTasks

So the easiest way to increase the performance is to minimize this part ((scale.end_date - scale.start_date) / scaleUnit)
It can be achieved quite simple - show big intervals of time using a bigger time step for the scale(‘month’ or ‘year’), and create additional config in order to display desired time intervals in ‘higher resolution’(with ‘days’ or ‘hours’) on demand.
The important thing is that you use small time units to show only the part of the time scale, so practically it would be zooming of needed periods.

In your last example scale displays 100 months and uses ‘day’ as a time step. That creates background grid with several thousand columns.
If you use weeks or month as units for the time scale, rendering time will be decreased significantly.

Related docs:
docs.dhtmlx.com/gantt/api__gantt … onfig.html
docs.dhtmlx.com/gantt/api__gantt … onfig.html
docs.dhtmlx.com/gantt/desktop__c … scale.html
docs.dhtmlx.com/gantt/desktop__d … scale.html

If none of this helps, and you still need to display many tasks with scale in days, there is some workarounds that are currently available only via internal api of the component.
You can speed up rendering if you overwrite method that responsible for rendering lines in the chart area, so it won’t render individual columns of the chart. Try following code:

[code]gantt._render_bg_line = function(item){
var odd = item.$index % 2 !== 0;
var cssTemplate = gantt.templates.task_row_class(item.start_date, item.end_date, item);
var css = “gantt_task_row” + (odd ? " odd" : “”) + (cssTemplate ? ’ '+cssTemplate : ‘’);
if(this.getState().selected_task == item.id){
css += " gantt_selected";
}

var row = document.createElement("div");
row.className = css;
row.style.height = (gantt.config.row_height)+"px";
row.setAttribute(this.config.task_attribute, item.id);
return row;

};
gantt.init(“gantt_here”);[/code]

BTW, I’ve tried to run gantt with bigger number in both loops (2k tasks total, 32k days in the time scale, the basic configuration and modified ‘gantt._render_bg_line’ method). I.e. generated test data following way:

[code] for (var i = 1; i < 1000; i++) {
date.setDate(date.getDate() + 1);
tasks.data.push({

});
}

	for (var i = 1; i < 1000; i++) {
		date.setMonth(date.getMonth() + 1);
		tasks.data.push({
			...
		});
	}[/code]

It still worked with a reasonable performance (Google Chrome, FF). However, showing the massive data sheet shouldn’t be a primary mode for the gantt. Optimization through configuration of the time scale is preferable.

Hi!

Thanks for your quick response. I have to disagree with you regarding your first comments, users will expect these days to view their massive schedule zooming in and out very frequently (from days to years and back ) and this to be instant;so performance is critical for a Gantt.

Regarding your suggestion I tried it and it works fine, great; maybe that should be an option to display those lines in the background. I think they can be useful when you move tasks around maybe; could it be possible to only render the lines that can be seen?

Hi, at the moment I’m using the free trial of dhtmlxGantt v 6.07.

After doing a quick update (previously I’m using v 4.0.1), I found that the data parsing is 7s faster than before, but the task updating (especially the “project” type) is still quite slow, about 32-36s.

I would like to know is this normal (because the whole data is about 1100 tasks) or is there any other way to improve the performance that is not stated here https://docs.dhtmlx.com/gantt/desktop__performance.html ?

I’ve tried using gantt.batchUpdate before doing looping as well, still no luck.

Any help is appreciated, thanks!

Hello,
The performance can be improved mostly by using the smart rendering extension and the static background (the free Standard version has show_task_cells instead of the static_background). But if you use additional layers, that might affect the performance.

Updating 1200 tasks after drag, takes around 17 seconds:
http://snippet.dhtmlx.com/ee111637c
But with the batchUpdate function it takes around 1 second:
http://snippet.dhtmlx.com/eac108f63

Hi ramil, thanks for the response.
I’ve used the smart rendering & the static background as well as the batchUpdate, but the update still longer than I expect.

Btw the previous developer was using these step to update “project” type ,

  • update all project children tasks progress value to database
  • get the database value and parse it in gantt.parse(jsonString)
  • get the childrens (use looping here) from task current id and use the values (progress, work, etc) to update the parent

I worried that the re-parse the gantt is the reason why the performance are quite heavy. Do you have any suggestion to improve the performance ?

Or there is a best practice to update “project” task somewhere in the documentation that I missed ?

Edit : I do use the additional layers, but even if I comment the code, it still not improving the performance.

Hello,
I received a ticket from you in the support system. Let’s continue our discussion there.