views:

225

answers:

3

I have this webpage : http://miloarc.pyrogenicmedia.com/

Which atm is nothing special. It has a few effects but none that break the bank.

If you mouse over a tile, it should change it's opacity to give it a fade effect. This is done through the Jquery Animation, not through CSS (I do this so it can fade, instead of being a straight change). Everything looks nice when the page loads, and the fades look perfect. Infact if you drag your mouse all over the place, if gives you a "trail" almost like a snake.

Anyway, My next problem is that you will see there is a box in the top left, which is going to tell you information about the tile you are hovering over. This seems to work fine. When you mouse over that information box, it switches it's position (So that you can reach the tiles that were previously hidden underneath it). From my understanding, this is all working fine, and to the letter.

However, After one move of the info box (One hover). Viewing the page in Firefox turns slugish. As in, after a successful move of the info box, the fade effects become very stuttered, and it doesn't pick up events as fast meaning you can't draw a "trail" on the screen.

Chrome doesn't have this issue. It seems to work fine no matter what. Safari also seems ok. Although I do notice if I move my mouse really fast, it does jump a bit but not as much as firefox.

Internet explorer doesn't work at all. Seems to crash the browser... And there is an error with the rounded corner plugin im using (Not sure why...).

All in all, I think whatever I'm doing inside my code must be heavily sluggish. But I don't know where it is happening.

Here is the full code, but I would advise go to the link to view everything.

        <script type="text/javascript">
        $(document).ready(function()
        {
            var WindowWidth = $(window).width();
            var WindowMod = WindowWidth % 20;
            var WindowWidth = WindowWidth - WindowMod;
            var BoxDimension = WindowWidth / 20;
            var BoxDimensionFixed = BoxDimension - 12;
            var dimensions = BoxDimensionFixed + 'px';


            $('.gamebutton').each(function(i)
            {
                $(this).css('width', dimensions);
                $(this).css('height', dimensions);
            });

            var OuterDivHeight = BoxDimension * 10;
            var TopMargin = ($(window).height() - OuterDivHeight) / 2;
            var OuterDivWidth = BoxDimension * 20;
            var LeftMargin = ($(window).width() - OuterDivWidth) / 2;
            $('#gamePort').css('margin-top', TopMargin).css('margin-left', LeftMargin).css('margin-right', LeftMargin);


            $('.gamebutton img').each(function(i)
            {
                $(this).hover(
                function () {
                $(this).animate({'opacity': 0.65});
                 },
                 function () {
                 $(this).animate({'opacity': 1});
                 }
                 ); 
            });

            $('.rounded').corners();

            $('.gamebutton').each(function(i)
            {
                $(this).hover(function()
                {
                    $('.gameTitlePopup').html($(this).attr('title'));
                    FadeActive();
                });
            });

            function FadeActive()
            {
                $('.activeInfo').fadeIn('slow');
            }

            $('#gameInfoLeft').hover(function()
            {
                $(this).removeClass('activeInfo');
                $(this).fadeOut('slow', function()
                {
                    $('#gameInfoRight').addClass('activeInfo');
                    FadeActive();
                });

            });

            $('#gameInfoRight').hover(function()
            {
                $(this).removeClass('activeInfo');
                $(this).fadeOut('slow', function()
                {
                    $('#gameInfoLeft').addClass('activeInfo');
                    FadeActive();
                });

            });
        });
    </script>

Thanks for any help :).

EDIT : Just to re-iterate my point. I'm looking to know why it only goes sluggish after moving the info box. Before this everything is absolutely fine. After moving the box (And moving it back), the UI just becomes super slow.

+1  A: 

jQuery runs faster when class selectors are more specific. $('.activeInfo') searches everything in the DOM for the specific class, but $('div.activeInfo') only selects the div(s), then the subset of divs that have the matching class.

You also have a rounded corners script active on all these same divs, which likely reduces rendering performance.

utt73
Correct. I want em rounded. They only get rounded at the start however, which then shouldn't affect performance from then on out. Especially since in Firefox, it is only using the -mox-radius CSS attribute anyway. I will however nail down the Selectors to be more specific.
Pyronaut
On further reading through your answer. It doesn't make much sense. My dom tree has pretty much ONLY got divs. There is no real way to nail it down as such. How can I point to div's, that is all there is on the page, so it won't make much difference.
Pyronaut
Have you tried it?
utt73
+1  A: 

Your performance results seem to be right down the line, as expected. Chrome is fastest, then Safari, Firefox, IE. (Although Safari 5, which was released today, is said to be comparable to Chrome.)

Maybe someone else will have other ideas, but the only thing I could think of would be to shorten the duration of the animation so each one ends more quickly and there's less overlap.

$(this).hover(
    function () {
         $(this).animate({'opacity': 0.65}, 300); // Try a quicker animation
    },
    function () {...

Not sure how much it will help, but it may be worth a shot.

FYI - When setting up event handlers on a jQuery object that represents a set of elements, you don't need to use each(). You can bind once to the entire set. So instead of this:

$('.gamebutton img').each(function(i) {
      $(this).hover(
         function () {
            $(this).animate({'opacity': 0.65});
         },
         function () {
             $(this).animate({'opacity': 1});
         }); 
 });

do this:

$('.gamebutton img').hover(
     function () {
        $(this).animate({'opacity': 0.65});
     },
     function () {
         $(this).animate({'opacity': 1});
     }); 

It won't help your performance problem, but it is the proper way to affect sets of elements.

patrick dw
I did know about that hover thing. For some reason last night I decided to use each, weird :P. And I did try shortening the animations slightly (I changed the opacity level to 0.80.) But now that I think about it, the animation will still last the same amount of time. I'll try that :)
Pyronaut
@Pyronaut - Let me know how it turns out. :)
patrick dw
Alrighty. Didn't work :(
Pyronaut
@Pyronaut - Sorry it didn't work :(. I see you removed the animation altogether. I don't know how much of the hit comes from backtracking over elements that are still animating, but you could always try putting a `stop()` before the animations like: `$(this).stop().animate({...`. Just another shot in the dark, I'm afraid. Or maybe test to see if they're animating: `if( !$(this).is(':animated') { $(this).animate({...`. Ultimately, slow js engines are just going to be slow. :(
patrick dw
@Pyronaut - Another thought is to use browser sniffing and only enable the animations for browsers that can handle it.
patrick dw
A: 

Javascript may just not be able to handle what you are doing. But don't give up before trying a few things:

  • Try to have the hover() function change the opacity immediately, and then use the fade only on the "unhover()" transition. This will then feel snappy but also smooth. I'd try that, as that will reduce your processing nearly half, and may be enough.

  • Look at the animate() method. You can tell it to complete all running animations before starting the next animation. So on hover, have it finish all the other animations before starting the next animation. This isn't ideal, but it will reduce your "tail" from dragging. This is a little incompatible with the first suggestion, so use your judgement.

  • The opacity functionality on IE uses a "filter". I don't know the details, but it seems to be heavier weight than raw Javascript. It is very problematic if you try to include text in the boxes. Anyway, you may need to try other approaches. You may just need to take different approaches on different browsers, losing a bit of the animation on the browsers that can't handle it.

  • There may be some way to create an "animate gif" that does the fading effect. Not sure about this approach-- just an idea.

All that being said, I have build a very similar page, with 17 images at a time, cross-fading to 17 other images. It performs well on all the browsers. Our design, though, is a little more forgiving-- the edges aren't so hard.

Good luck. I'll check back if I have any other ideas.

ndp
Alright. I took your changes on board. And infact I removed the JQuery hover effects totally, and made them into CSS. Still, I am getting the same slow down that I saw before. But once again, Still only after the info box is moved.
Pyronaut