Looking for thoughts on inprovement of my javascript (jquery) code. Recursive function
===

I have made this code that makes some visual "tiles" that fades in and out. 
But at the moment I'm having a little performance problem.

The whole code in action can be seen here: [userhome.org](http://www.userhome.org/)


Though most browers are running the code okay (especially firefox), some like safari have problems after a while (a while = like 15 seconds).

I think its due to my recursive function (the function named <b>changeopacity</b> that calls itself forever on a delay)? or is it?

But anyways the problem is that this code is really heavy for most browsers. Is there, or more how can I make this code perform any better? any thoughts? (code examples would be nice) thanks :-)

The actual code:
<!-- language: lang-js -->
    
    $(document).ready(function () {
		
		var aniduration = 2000;
		var tilesize = 40;
	
		createtable(tilesize);
		
		
		
		$(".tile").each(function (index, domEle) {
			var randomdelay = Math.floor(Math.random() * 3000);
			setTimeout(function () {
				changeopacity(aniduration, domEle);
			}, randomdelay);
		});
		
		
		
		$("td").click(function () {
			clickanimation(this, 9);
		});
		
		$("td").mouseenter(function () {
			var element = $(this).find("div");
			$(element).clearQueue().stop();
			$(element).animate({opacity: "0.6"}, 800);
		});
		
		
		$("td").css("width", tilesize + "px").css("height", tilesize + "px");
		

		
	});

	function createtable(tilesize) {
		var winwidth = $(window).width();
		var winheight = $(window).height();
		var horztiles = winwidth / tilesize;
		var verttiles = winheight / tilesize;
	
	
	for (var y = 0; y < verttiles; y++)
	{
		var id = "y" + y;
		$("#tbl").append("<tr id='" + id + "'></tr>");
		
		for (var x = 0; x < horztiles; x++)
		{
			$("#" + id).append("<td><div class='tile' style='opacity: 0; width: " + tilesize + "px; height: " + tilesize + "px;'></div></td>");
		}
	}	
	}

	function changeopacity(duration, element){
		var randomnum = Math.floor(Math.random() * 13);
		var randomopacity = Math.floor(Math.random() * 7);
		var randomdelay = Math.floor(Math.random() * 1000);
		
		if ($(element).css("opacity") < 0.3)
		{
			if (randomnum != 4)
			{
				if ($(element).css("opacity") != 0)
				animation(element, 0, duration, randomdelay);
			}
			else
			{
				animation(element, randomopacity, duration, randomdelay);
			}
		}
		else
		{
			animation(element, randomopacity, duration, randomdelay);
		}
		
		setTimeout(function () {
			return changeopacity(duration, element);
		}, duration + randomdelay);
	}
	
	function animation(element, randomopacity, duration, randomdelay){
		$(element).clearQueue().stop().delay(randomdelay).animate({opacity: "0." + randomopacity}, duration);
	}
	
	
	function clickanimation(column, opacitylevel) {
			var element = $(column).find("div");
			$(element).clearQueue().stop();
			$(element).animate({"background-color": "white"}, 200);
			$(element).animate({opacity: "0." + opacitylevel}, 200);
			$(element).delay(200).animate({opacity: "0.0"}, 500);
			//$(element).delay(600).animate({"background-color": "black"}, 500);
	}

	


