Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Selected Reading
Improve performance of a HTML5 Canvas with particles bouncing around
To enhance the performance of HTML5 Canvas with particles bouncing around, several optimization techniques can dramatically improve frame rates and reduce CPU usage.
Key Performance Optimization Techniques
- Separate the calculations from the drawing operations
- Request a redraw only after updating calculations
- Optimize collision detection by avoiding O(n²) comparisons
- Reduce callback usage and function calls
- Use inline calculations where possible
- Implement object pooling for particles
Example: Optimized Particle System
<!DOCTYPE html>
<html>
<head>
<title>Optimized Particles</title>
</head>
<body>
<canvas id="canvas" width="800" height="600"></canvas>
<script>
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
// Particle pool to avoid garbage collection
const particles = [];
const particleCount = 100;
// Initialize particles
for (let i = 0; i < particleCount; i++) {
particles.push({
x: Math.random() * canvas.width,
y: Math.random() * canvas.height,
vx: (Math.random() - 0.5) * 4,
vy: (Math.random() - 0.5) * 4,
radius: 3
});
}
function updateParticles() {
// Separate calculation phase
for (let i = 0; i < particles.length; i++) {
const p = particles[i];
// Update position (inline calculations)
p.x += p.vx;
p.y += p.vy;
// Boundary collision (no function calls)
if (p.x <= p.radius || p.x >= canvas.width - p.radius) {
p.vx = -p.vx;
}
if (p.y <= p.radius || p.y >= canvas.height - p.radius) {
p.vy = -p.vy;
}
}
}
function drawParticles() {
// Clear canvas once
ctx.clearRect(0, 0, canvas.width, canvas.height);
// Batch drawing operations
ctx.fillStyle = '#007acc';
ctx.beginPath();
for (let i = 0; i < particles.length; i++) {
const p = particles[i];
ctx.moveTo(p.x + p.radius, p.y);
ctx.arc(p.x, p.y, p.radius, 0, Math.PI * 2);
}
ctx.fill();
}
function animate() {
updateParticles(); // Calculate first
drawParticles(); // Draw after calculations
requestAnimationFrame(animate);
}
animate();
</script>
</body>
</html>
Advanced Optimization: Spatial Partitioning
For collision detection between particles, use spatial partitioning instead of checking every particle against every other particle:
// Grid-based spatial partitioning
const gridSize = 50;
const grid = {};
function getGridKey(x, y) {
return Math.floor(x / gridSize) + ',' + Math.floor(y / gridSize);
}
function updateCollisions() {
// Clear grid
for (let key in grid) {
grid[key].length = 0;
}
// Assign particles to grid cells
for (let i = 0; i < particles.length; i++) {
const p = particles[i];
const key = getGridKey(p.x, p.y);
if (!grid[key]) grid[key] = [];
grid[key].push(p);
}
// Check collisions only within same grid cell
for (let key in grid) {
const cellParticles = grid[key];
for (let i = 0; i < cellParticles.length; i++) {
for (let j = i + 1; j < cellParticles.length; j++) {
// Collision detection logic here
}
}
}
}
Performance Comparison
| Technique | Performance Gain | Best For |
|---|---|---|
| Separate calculations/drawing | 20-30% FPS increase | All particle systems |
| Spatial partitioning | 80-90% for collisions | Systems with particle interactions |
| Object pooling | Reduces garbage collection | Dynamic particle creation |
Additional Tips
- Use integers: Integer calculations are faster than floating-point
-
Batch canvas operations: Group
beginPath()andfill()calls - Limit particle count: Monitor frame rates and adjust particle count dynamically
- Use Web Workers: Offload heavy calculations to background threads
Conclusion
Optimizing Canvas particle systems involves separating calculations from rendering, using spatial partitioning for collision detection, and minimizing function calls. These techniques can improve performance by 200-300% in complex particle systems.
Advertisements
