html5/javascript game running slow in ie8

We have made a game in html/javascript. There's unfortunately a lot of secrecy around the project, so I can't disclose much code.

However the essence is that it runs extremely well on all browsers, except ie. through using the <meta http-equiv="X-UA-Compatible" content="IE=9"> tag; now the only problem is ie8, which the game NEEDS to be compatible with. I know it has little html5 integration, but the game actually works, except it's horribly slow.

Keep in mind, ie9 and ie10 were very slow before using the tag as well. The game is in n sense advanced or anything. So I was wondering if anyone knew what could cause issues like these?

I'll try to put some obfuscated code here, keep in mind though that it's not the entire code, just the main loop:

    // Global constants:
var PLAYGROUND_WIDTH    = 1000;
var PLAYGROUND_HEIGHT    = 1000;
var REFRESH_RATE        = 30;

//Constants for the gameplay
var smallStarSpeed        = 1; //pixels per frame

var mediumStarSpeed       = 3; //pixels per frame

var bigStarSpeed          = 5; //pixels per frame

var percent = 1;

// --------------------------------------------------------------------
// --                      the main declaration:                     --
// --------------------------------------------------------------------

$(function(){
//Calculate playground width and height:
PLAYGROUND_WIDTH = $(window).width() - 20;
PLAYGROUND_HEIGHT = $(window).height() - 20;

//Calculate Layour for responsive Design.
//Calculate Area:


// Animations declaration: 
// The background:    

var DM = new DeckManager;
var IM = new ImageManager;

IM.Create("Image1");


//DEBUG: Loading images for demo, this should be done using the image manager in the actual game.
var background1 = new $.gameQuery.Animation({
    imageURL: "http://gamequeryjs.com/demos/3/background1.png"});
var background2 = new $.gameQuery.Animation({
    imageURL: "http://gamequeryjs.com/demos/3/background2.png"}); 
var background3 = new $.gameQuery.Animation({
    imageURL: "http://gamequeryjs.com/demos/3/background3.png"});
var background4 = new $.gameQuery.Animation({
    imageURL: "http://gamequeryjs.com/demos/3/background4.png"});
var background5 = new $.gameQuery.Animation({
    imageURL: "http://gamequeryjs.com/demos/3/background5.png"});
var background6 = new $.gameQuery.Animation({
    imageURL: "http://gamequeryjs.com/demos/3/background6.png"});



    var Face = new Array();
    IM.Load("image2");
    IM.Load("image3");
    IM.Load("image4");
            IM.Load("image5");


            var resizeTimer;

//Event to handle resizing
//This event should fire under any circimstance, except when safari is NOT maximized, and windows resolution is changed (WTF?)
$(window).resize(function () 
{
    clearTimeout(resizeTimer);
    resizeTimer = setTimeout(Resized, 100);
});

//Actual Resizing Event
function Resized() 
{
    //Your function goes here


    //Calculate playground width and height:
    PLAYGROUND_WIDTH = $(window).width() - 20;
    PLAYGROUND_HEIGHT = $(window).height() - 20;

    //Calculate Layout for responsive Design.
};


// Initialize the game:
$("#playground").playground({
    height: PLAYGROUND_HEIGHT, 
    width: PLAYGROUND_WIDTH, 
    keyTracker: true,
    mouseTracker: true});

// Initialize the background
$.playground()
    .addGroup("background", {width: PLAYGROUND_WIDTH, 
                             height: PLAYGROUND_HEIGHT})
    .addSprite("background1", {animation: background1, 
                               width: PLAYGROUND_WIDTH, 
                               height: PLAYGROUND_HEIGHT})  
    .addSprite("background2", {animation: background2,
                               width: PLAYGROUND_WIDTH, 
                               height: PLAYGROUND_HEIGHT, 
                               posx: PLAYGROUND_WIDTH})
    .addSprite("background3", {animation: background3, 
                               width: PLAYGROUND_WIDTH, 
                               height: PLAYGROUND_HEIGHT})
    .addSprite("background4", {animation: background4, 
                               width: PLAYGROUND_WIDTH, 
                               height: PLAYGROUND_HEIGHT, 
                               posx: PLAYGROUND_WIDTH})
    .addSprite("background5", {animation: background5, 
                               width: PLAYGROUND_WIDTH, 
                               height: PLAYGROUND_HEIGHT})
    .addSprite("background6", {animation: background6, 
                               width: PLAYGROUND_WIDTH, 
                               height: PLAYGROUND_HEIGHT, 
                               posx: PLAYGROUND_WIDTH})
    $("#background").addSound(bgmusic);
//Setup obects so they can be reached randomly
var Vals = new Array();
var Vals2 = new Array();
var Turned = 0;
var TurnedMax = 2;

//This will ensure that two cards of each are added to the deck
//This function will be handled by the imagemanager at later stages.
for (var i = 0; i < NumberOfCards; ++i)
{
    Vals[i] = Math.floor(i/2);
}

Vals2[0]=3;

DM.Create(Vals, Vals2, NumberOfCards, 1);

//Generate the actual object

    $.playground()
    .addGroup("object", {width: PLAYGROUND_WIDTH, 
                             height: PLAYGROUND_HEIGHT})

for (var i = 0; i < NumberOfCards+1; ++i)
{
    //Generate unique ID for the card
    var name = "object"+i;

    val = DM.Pushobject();

    //Add the actual card to the playground, we spawn them in a responsive awy based on the resolution of the game.
    $("#object").addSprite(name, {animation: IM.GetBack(), width: 208, height: 303, posx: (i%(Math.ceil(noc*Ratio))) *SpaceX + SpaceX - 104 + LastYOff * (  i>=  (NumberOfCards + NumberOfCardsBonus) - ((NumberOfCards + NumberOfCardsBonus)%(Math.ceil(noc*Ratio))) ) , posy: Math.floor( i / (Math.ceil(noc*Ratio))  ) * SpaceY + SpaceY - 152 });//

    //Add a class to the object, this, does nothing except make us able to search for objects with the same class later in the code.
    $("#"+name).addClass("object");

    //Create the actual class for the object, this will add logic to the object.
    $("#"+name)[0].Cards = new Cards($("#"+name));
    $("#"+name)[0].Cards.Create(val, IM.GetImage(val), IM.GetImage(3), IM.GetBack(), DM.LastBonus(), Scale);


    //Add a mousedown event for the card, this mousedown will be run in the main
    //environment rather than the class environment to make sure that we have access
    //to all the data we need access to.
    $("#"+name).mousedown(function(e)
    {
        var Ready = 0;
        $(".object").each(function()
        {
            if (this.object.visible && (this.object.Turning==true || this.object.FlippedV==true))
            {
                Ready++;
            }
        });
        //Find all the objects with the tag/class card.
        $(".object").each(function()
        {
            //Check if the mouse clicked the object, if it's still part of the game, and if it has not been flipped.
            if (e.clickedobject
            && Ready<TurnedMax)
            {
                //Run the clicked event for the card, this will start events etc.
                this.object.Clicked();
                //Increase the turned counter, if we have turned the correct amount of objectto be compared
                //then compare them.
                if (this.Cards.Bonus == false)
                {
                    Turned++;
                    if (Turned==TurnedMax)
                    {
                        //We have turned the amount of object needed
                        //Find out which value the first object has, and use this as a base to compare if cards match.
                        //Also instantiate a counter for the amount of cards actually matching.
                        //It's done this way if you want a variable number of object needed for a match.
                        var Correct = this.object.value;
                        var CorrectAmount = 0;
                        $(".object").each(function()
                        {
                            //For each card, if they are flipped, are not going into hiding/deletion, and has the
                            //Correct value, increase the counter for the number of objects matching.
                            if (this.object.Flipped == true && this.object.Hiding==0 && this.object.value == Correct)
                                CorrectAmount++;

                        });

                        //If we have a correct match
                        if (CorrectAmount==TurnedMax)
                        {
                            $(".object").each(function()
                            {
                                //Foreach object that is flipped and not in hiding, delete them (aka. yay, you got a match).
                                if (this.object.Flipped==true && this.object.Hiding==0)
                                    this.object.SetVisible(false);
                            });
                        }

                        $(".object").each(function()
                        {
                            //Foreach objectthat was not in hiding and was not part of the match, unflip them again.
                            if (this.object.Flipped==true && this.object.Hiding==0)
                            this.object.Hide();
                        });

                        Turned=0;
                    }
                }
            }
        });
    });


}

// this sets the id of the loading bar (NOT USED YET):
$.loadCallback(function(percent){
        $("#loadingBar").width(400*percent);
  });
//initialize the start button
$("#startbutton").click(function(){
    $.playground().startGame(function(){
        $("#welcomeScreen").remove();
    });
})


//This is for the background animation (DEBUG)
$("#playground").registerCallback(function(){

$("#background1").x(($("#background1").x() + smallStarSpeed +PLAYGROUND_WIDTH) % (2 * PLAYGROUND_WIDTH) - PLAYGROUND_WIDTH);
$("#background2").x(($("#background2").x() + smallStarSpeed +PLAYGROUND_WIDTH) % (2 * PLAYGROUND_WIDTH) - PLAYGROUND_WIDTH);

$("#background3").x(($("#background3").x() + mediumStarSpeed +PLAYGROUND_WIDTH) % (2 * PLAYGROUND_WIDTH) - PLAYGROUND_WIDTH);
$("#background4").x(($("#background4").x() + mediumStarSpeed +PLAYGROUND_WIDTH) % (2 * PLAYGROUND_WIDTH) - PLAYGROUND_WIDTH);

$("#background5").x(($("#background5").x() + bigStarSpeed +PLAYGROUND_WIDTH) % (2 * PLAYGROUND_WIDTH) - PLAYGROUND_WIDTH);
$("#background6").x(($("#background6").x() + bigStarSpeed +PLAYGROUND_WIDTH) % (2 * PLAYGROUND_WIDTH) - PLAYGROUND_WIDTH);


//Basic Game Engine!!

$(".object").each(function()
{
    //For each card, perform their step event.
    this.object.Step();
});

}, REFRESH_RATE);
});

Upvotes: 2

Views: 620

Answers (2)

Spudley
Spudley

Reputation: 168853

You say you're using <meta http-equiv="X-UA-Compatible" content="IE=9">.

That's is unlikely to be helpful in any way at all.

It will have no effect at all in IE9 or IE8.

It will be having an effect in IE10 and IE11, but that effect will be to pull the browser down into backward-compatibility mode, which basically means that you're telling IE10 and higher to switch off some of their newer features and pretend to be IE9.

There's really no point in that at all; in fact, it's probably doing more harm than good, so I recommend removing that line of code entirely.

If you must have an X-UA-Compatible flag, the only sensible value for it is IE=edge. This will force all IE versions to use the best mode they have available. That's the default anyway in most cases, but it might help in the few cases where the default is something else.

But the real problem you're complaining about here is performance, and I can tell you categorically that this is entirely unrelated to the X-UA-Compatible flag -- as I say, the way you have it set won't have any effect on IE8 at all anyway, so it's not that which is slowing things down.

Ultimately, your problem with IE8 may boil down to the simple fact that it is just a much much slower browser than later versions. It is possible that you may simply not be able to get IE8 to perform well enough to achieve what you want.

IE9 and IE10 are much better, so you should be able to get reasonable performance from them with a bit of tweaking, so your best hope would probably be to do some performance tuning.

And the best bet for performance testing is to upgrade to IE11, which has much better dev tools than IE10, including some really good tools for analysing your site's performance.

Performance tuning is big topic in itself (out of scope for this answer), but the ultimate goal is to work out what is causing your biggest bottlenecks, and fix those. In most cases there's generally just one or two major issues that hold everything up, and dealing with them is usually sufficient to make the difference.

So my advice is: Download IE11 and try out the new performance testing features in the new dev tools. Hopfully that'll be enough to get you started, but if you still can't find the problem, try asking a more specific question about whay a particular bit of your code is slow.

One other thing I would suggest is maybe to try reducing your use of libraries like jQuery.

jQuery is incredibly useful, but it does have a performance impact. Try switching to native Javascript where possible.

And where you can't, try reducing the number of times you make the same call. For example:

$("#background1").x(($("#background1").x() + smallStarSpeed +PLAYGROUND_WIDTH) % (2 * PLAYGROUND_WIDTH) - PLAYGROUND_WIDTH);

This calls $("#background1") twice. Do this instead:

var $bg1 = $("#background1");
$bg1.x(($bg1.x() + smallStarSpeed +PLAYGROUND_WIDTH) % (2 * PLAYGROUND_WIDTH) - PLAYGROUND_WIDTH);

Better yet, if you can do it with document.getElementByTagName rather than jQuery, you'll save yourself even more performance.

I also notice that you're repeating some calculations in that code. Obviously, if you can tidy that up to reduce the repeats, it will also help.

I hope that's given you some directions to think.

Upvotes: 4

Dhrumil Shah
Dhrumil Shah

Reputation: 746

Put <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE9" > in your html head tag and try. Switching the compatibility view on turns IE into IE8 rendering.

http://html5test.com/compare/browser/ie08/chrome28/ff22.html

Upvotes: 0

Related Questions