can we make this as it is but much much much more efficient? so less hanging of my web app due to this , import React, { useEffect, useRef } from 'react';

const SubtleBackground = () => {
  const canvasRef = useRef(null);

  useEffect(() => {
    const canvas = canvasRef.current;
    const ctx = canvas.getContext('2d');
    let animationFrameId;
    let time = 0;

    const resizeCanvas = () => {
      canvas.width = window.innerWidth;
      canvas.height = window.innerHeight;
    };

    const grayColors = [
      '#F8F9FA', '#E9ECEF', '#DEE2E6', '#CED4DA', 
      '#ADB5BD', '#6C757D', '#495057', '#343A40'
    ];
    const accentColors = ['#4285F4', '#34A853', '#FBBC05', '#EA4335'];

    class Rose {
      constructor(width, height) {
        this.centerX = Math.random() * width;
        this.centerY = Math.random() * height;
        this.maxRadius = Math.min(width, height) * (0.15 + Math.random() * 0.1);
        this.n = Math.floor(Math.random() * 5) + 3;
        this.d = Math.floor(Math.random() * 5) + 3;
        this.isAccent = Math.random() < 0.1; // 10% chance of being an accent color
        this.color = this.isAccent 
          ? accentColors[Math.floor(Math.random() * accentColors.length)]
          : grayColors[Math.floor(Math.random() * grayColors.length)];
        this.phase = Math.random() * Math.PI * 2;
        this.opacity = 0;
      }

      draw(ctx, time) {
        ctx.beginPath();
        ctx.lineWidth = 1.5;
        
        const gradient = ctx.createRadialGradient(this.centerX, this.centerY, 0, this.centerX, this.centerY, this.maxRadius);
        gradient.addColorStop(0, this.color + Math.floor(this.opacity * 55).toString(16).padStart(2, '0'));
        gradient.addColorStop(1, this.color + '03');

        ctx.strokeStyle = gradient;

        for (let theta = 0; theta < Math.PI * 20; theta += 0.02) {
          const k = this.n / this.d;
          const r = this.maxRadius * Math.sin(k * (theta + this.phase + time * 0.1));
          const x = this.centerX + r * Math.cos(theta);
          const y = this.centerY + r * Math.sin(theta);

          if (theta === 0) {
            ctx.moveTo(x, y);
          } else {
            ctx.lineTo(x, y);
          }
        }

        ctx.stroke();
      }

      update() {
        if (this.opacity < 0.5) {
          this.opacity += 0.005;
        } else {
          this.opacity -= 0.005;
        }
        return this.opacity > 0;
      }
    }

    let roses = [];

    const draw = () => {
      ctx.fillStyle = 'rgba(252, 252, 253, 0.1)';
      ctx.fillRect(0, 0, canvas.width, canvas.height);

      roses = roses.filter(rose => rose.update());

      if (roses.length < 8) {
        roses.push(new Rose(canvas.width, canvas.height));
      }

      roses.forEach(rose => rose.draw(ctx, time));

      time += 0.01;
      animationFrameId = requestAnimationFrame(draw);
    };

    resizeCanvas();
    draw();

    window.addEventListener('resize', resizeCanvas);

    return () => {
      cancelAnimationFrame(animationFrameId);
      window.removeEventListener('resize', resizeCanvas);
    };
  }, []);

  return (
    <canvas
      ref={canvasRef}
      style={{
        position: 'fixed',
        top: 0,
        left: 0,
        width: '100%',
        height: '100%',
        zIndex: -1,
        pointerEvents: 'none',
      }}
    />
  );
};

export default SubtleBackground; , can we make this as it is but much much much more efficient? so less hanging of my web app due to this