A comprehensive debugging and performance analysis tool for DHTMLX Gantt chart libraries that provides detailed execution statistics, performance metrics, and optimization insights.
Source Code: react_client/src/assets/gantt/debugger.js
- Function Wrapping: Automatically wraps all Gantt chart functions with performance monitoring
- Detailed Statistics: Comprehensive metrics including execution time, call frequency, memory usage, and error tracking
- Performance Analysis: Percentile calculations, standard deviation, and efficiency metrics
- Hotspot Detection: Identifies performance bottlenecks and optimization opportunities
- Memory Monitoring: Tracks memory usage changes during function execution (Chrome/Chromium browsers)
- Call Stack Analysis: Monitors function call depth and patterns
- Error Tracking: Captures and reports function execution errors
- Built-in Exclusions: Automatically excludes frequently called functions like
getState,assert,checkEvent
Copy the entire GanttDebugger class from react_client/src/assets/gantt/debugger.js.
- Chrome/Edge: Press
F12orCtrl+Shift+I(Windows/Linux) /Cmd+Option+I(Mac) - Firefox: Press
F12orCtrl+Shift+K(Windows/Linux) /Cmd+Option+K(Mac) - Safari: Press
Cmd+Option+I(Mac) - Enable Developer menu first in Safari preferences
Click on the "Console" tab in the developer tools.
- Paste the entire GanttDebugger code into the console
- Press
Enterto execute it - You should see:
π§ GanttDebugger initialized
// Find your gantt instance (common variable names)
// Try one of these based on your Gantt library:
const debugger = new GanttDebugger(gantt); // dhtmlxGantt
// const debugger = new GanttDebugger(ganttChart); // If your variable is ganttChart
// const debugger = new GanttDebugger(myGantt); // If your variable is myGantt
// const debugger = new GanttDebugger(window.gantt); // If gantt is globalInteract with your Gantt chart (add tasks, scroll, resize, etc.). The debugger is now monitoring all function calls.
// Print detailed statistics (includes console output)
const stats = debugger.getStats();
// Print performance hotspots (includes console output)
const hotspots = debugger.getHotspots();// Paste GanttDebugger code first, then:
const debugger = new GanttDebugger(gantt);
// Do some operations that might be slow
// click stuff
// reorder
// create
// etc.
// Check what's taking time
debugger.getHotspots();// Paste GanttDebugger code first, then:
const debugger = new GanttDebugger(gantt);
// Perform operations that might leak memory
for(let i = 0; i < 100; i++) {
gantt.addTask({id: i, text: `Task ${i}`});
}
// Check memory usage
const stats = debugger.getStats();
stats.filter(s => s.avgMemoryDelta > 50).forEach(s =>
console.log(`${s.function}: ${s.avgMemoryDelta.toFixed(1)}KB avg memory usage`)
);// Paste GanttDebugger code first, then:
const debugger = new GanttDebugger(gantt);
// Test current performance
performYourOperations();
const beforeStats = debugger.getStats();
console.log('Before optimization:', beforeStats.slice(0, 5));
// Reset and test after changes
debugger.reset();
performYourOptimizedOperations();
const afterStats = debugger.getStats();
console.log('After optimization:', afterStats.slice(0, 5));If you're not sure what your gantt variable is called, try these in the console:
// Check common variable names
console.log('gantt:', typeof gantt);
console.log('ganttChart:', typeof ganttChart);
console.log('myGantt:', typeof myGantt);
// Search in window object
Object.keys(window).filter(key => key.toLowerCase().includes('gantt'));
// Or look for objects with gantt-like methods
Object.keys(window).filter(key => {
const obj = window[key];
return obj && typeof obj === 'object' &&
(obj.render || obj.parse || obj.addTask);
});// If debugger seems not to work:
console.log('Debugger active:', debugger.isActive);
console.log('Functions wrapped:', debugger.originalFunctions.size);
console.log('Stats collected:', debugger.stats.size);
// Check if gantt instance is valid
console.log('Gantt instance:', debugger.ganttInstance);
console.log('Gantt methods:', Object.getOwnPropertyNames(debugger.ganttInstance).filter(prop =>
typeof debugger.ganttInstance[prop] === 'function'
));// Stop monitoring but keep wrappers
debugger.stop();
// Start monitoring again
debugger.start();
// Completely remove debugger and restore original functions
debugger.destroy();
// Verify cleanup
console.log('Debugger destroyed:', !debugger.isActive);new GanttDebugger(ganttInstance)Parameters:
ganttInstance(required): Your Gantt chart instance
Built-in Settings:
- Automatically excludes:
getState,assert,checkEvent - Tracks last 10 calls per function
- Memory monitoring (Chrome/Chromium only)
- Auto-starts monitoring on creation
debugger.start() // Start monitoring
debugger.stop() // Stop monitoring (keeps wrappers)
debugger.reset() // Reset all statistics
debugger.destroy() // Remove all wrappers and restore original functionsdebugger.getStats() // Get statistics array AND print to console
debugger.getHotspots() // Get hotspots object AND print to consoleNote: Both getStats() and getHotspots() automatically print formatted output to the console and return data objects.
π ADVANCED GANTT FUNCTION EXECUTION STATISTICS
===============================================
π Total: 1,234 calls in 567.890ms
===============================================
1. π§ render
π Executions: 45 (2.34/sec)
β±οΈ Total Time: 234.567ms
π Avg: 5.2126ms | Min: 1.2340ms | Max: 15.6780ms
π Percentiles: P50=4.5600ms | P90=8.9000ms | P95=12.3400ms
π StdDev: 2.3456ms | Efficiency: 8.76 calls/ms
π― Stack Depth: 1.2 avg | Memory: 45.6KB avg
π Recent calls: 4.56ms, 5.23ms, 3.78ms, 6.12ms, 4.89ms
π₯ PERFORMANCE HOTSPOTS
=======================
π Slowest functions (by avg time):
1. complexCalculation: 15.6789ms avg
2. heavyRendering: 12.3456ms avg
π Most called functions:
1. updateView: 456 calls
2. processData: 234 calls
β° Biggest time consumers:
1. render: 234.567ms total
2. processData: 123.456ms total
β Most error-prone functions:
1. validateData: 5.2% error rate
{
function: "functionName",
executions: 45,
totalTime: 234.567,
avgTime: 5.2126,
minTime: 1.2340,
maxTime: 15.6780,
stdDev: 2.3456,
percentiles: {
p50: 4.5600,
p90: 8.9000,
p95: 12.3400,
p99: 14.2300
},
errors: 2,
errorRate: 4.44,
callsPerSecond: 2.34,
avgStackDepth: 1.2,
avgMemoryDelta: 45.6,
efficiency: 8.76,
recentCalls: [...]
}const debugger = new GanttDebugger(gantt);
// Perform operations you want to analyze
gantt.parse(largeDataSet);
gantt.render();
// Identify bottlenecks
const hotspots = debugger.getHotspots();
// Check console output for detailed analysisconst debugger = new GanttDebugger(gantt);
// Monitor memory usage over time
const stats = debugger.getStats();
stats.forEach(stat => {
if (stat.avgMemoryDelta > 100) { // Functions using >100KB
console.warn(`Memory concern: ${stat.function} uses ${stat.avgMemoryDelta}KB avg`);
}
});const debugger = new GanttDebugger(gantt);
// After operations that might fail
const hotspots = debugger.getHotspots();
if (hotspots.errorProne.length > 0) {
console.log('Functions with errors:', hotspots.errorProne);
}// Before changes
const debugger = new GanttDebugger(gantt);
performStandardOperations();
const baselineStats = debugger.getStats();
debugger.reset();
// After changes
performStandardOperations();
const newStats = debugger.getStats();
// Compare performance
newStats.forEach(newStat => {
const baseline = baselineStats.find(s => s.function === newStat.function);
if (baseline && newStat.avgTime > baseline.avgTime * 1.1) {
console.warn(`Performance regression in ${newStat.function}: ${newStat.avgTime}ms vs ${baseline.avgTime}ms`);
}
});-
Functions not being wrapped
- Ensure the gantt instance is passed correctly
- Check if functions are already wrapped or protected
- Functions starting with
_or$are automatically excluded
-
Memory statistics showing 0
performance.memoryis only available in Chrome/Chromium browsers- Other browsers will show 0 for memory statistics
-
Performance impact
- The debugger adds minimal overhead (~0.1ms per function call)
- Use
stop()to pause monitoring without removing wrappers - Use
destroy()to completely remove monitoring
-
No statistics showing
- Check if
debugger.isActiveistrue - Verify your gantt instance has callable methods
- Ensure you're interacting with the gantt after creating the debugger
- Check if
The debugger automatically excludes these frequently called functions to reduce noise:
getStateassertcheckEvent
These functions are typically called very frequently (especially during mouse movements) and would clutter the statistics.
MIT License - Feel free to use, modify, and distribute as needed.
Happy debugging! ππ§