开发者

What can I do to optimize my ajax application for IE7/IE8 in order to avoid "Stop running this script"?

开发者 https://www.devze.com 2023-03-06 12:06 出处:网络
I have a booking engine which is pretty sluggish in IE7. It\'s ajaxified and hash/window onchange based. There are 5 total steps. The main issue I\'m having is step 2 is uber slow in IE.

I have a booking engine which is pretty sluggish in IE7. It's ajaxified and hash/window onchange based. There are 5 total steps. The main issue I'm having is step 2 is uber slow in IE.

When a user lands on step 2, an ajax request is made to pull in data with web services in order to display hotel rooms. The hotel rooms are divided by the main room type and more specific types inside. The JS functionality that gets applied to the hotel rooms consist of:

  • accordion on the rooms
  • accordion on the room types (nested accordion)
  • quickflip on the image
  • jscrollpane, custom scrollbar on the room description on the left after the image flips
  • jscrollpane, custom scrollbar on the room types on the right

All of this causes the famous:

What can I do to optimize my ajax application for IE7/IE8 in order to avoid "Stop running this script"?

I've googled and landed on this, this, and this.

So obviously the cause is that there are too many script statements executing sequentially within a specific amount of time in IE.

I basically need to refactor my code and optimize it such that there are delays in between function invocations.

The way I'm injecting the HTML after doing the ajax request is:

 734                     $( o.html ).appendTo( el )

o.html is a reference to the JSON objects html property which is derived from here.

Then, the code below runs:

setTimeout(function () {


    $('#roomz .room-accordion').each(function () {

        $(this).accordion({
            header: 'h2.new-heading',
            autoheight: false,
            clearStyle: true,
            collapsible: true,
            change: function (event, ui) {
                window.ui = ui;

                // if it hasnt been quickflipped/subnest accordioned, do it
                if (!$(ui.newContent).data('enabled')) {
                    $('.room-rates', ui.newContent).each(function () {

                        $(this).accordion({
                            header: 'h4.rate-name',
                            autoheight: false,
                            active: 0,
                            clearStyle: true
                        });

                        //if (!$.browser.msie) 
                           $(this).jScrollPane();

                    })

                    $('.room-image', ui.newContent).quickFlip({
                        vvertical: true
                        //easing:'easeInBounce'
                        //easing:'easeInSine'
                    });

                    $('.back-copy-inner', ui.newContent).jScrollPane({
                        verticalDragMaxHeight: 131
                    });

                    $(ui.newContent).data('enabled', true);
                }
            }
        })

        var el = this;
        setTimeout(function () {
            $('.back-copy-inner:eq(0)', el).jScrollPane({
                verticalDragMaxHeight: 131
            });
        }, 500);

        $('.room-rates:eq(0)', this).each(function () {

            $(this).accordion({
                header: 'h4.rate-name',
                autoheight: false,
                active: 0,
                clearStyle: true
            });

            var el = this;
            setTimeout(function () {
                //if (!$.browser.msie) 
                $(el).jScrollPane();
            }, 50);
开发者_JAVA技巧
        });

        $('.room-image:eq(0)', this).quickFlip({
            vvertical: true
            //easing:'easeInBounce'
            //easing:'easeInSine'
        });

        $('.room:eq(0)', this).data('enabled', true);

    });



}, 20);

My first version of the code basically applied the quickflip and scrollpanes to every room whether it was hidden in the accordion or not. The refactored version ( live/current one ) applies it to the very first room that's active in the accordion, and when another is clicked on through the accordion, I apply the quickflip and scrollpane to it.

I added a setTimeout around the entire thing, because this happens after the HTML gets injected. I have setTimeouts inside as well.

It seems like it's still too slow. Can anyone offer any refactoring/optimization tips?

My ideas for refactoring it again consist of:

  1. instead of doing an .each on .room accordion, apply a repeating operation to force a delay in between each iteration like this?
  2. optimize and minify the HTML returned by the ajax even more - I have already done lots of optimization, killed whitespace, dont show HTML comments, etc..
  3. Enabling Gzip
  4. Doing lazy loading on the images so that only the visible accordion content images show and others are blank.gif until you activate them through the accordion
  5. Instead of returning the HTML and dumping it, return only relevant data with NO HTML and instead build the HTML with a templating engine?!

If anyone can offer opinions on my ideas for refactoring in terms of which ones would produce the best results, that'd be great too.

LINKS:

  • the page in question is this.
  • the relevant JS is here.
  • the relevant code/line numbers start at line 829 of new.js ( thats the snippet I pasted )
  • the relevant ajax request that is made is made to this page.

PS - not supporting IE6

EDIT: I put a delay between iteration of .each and it's still uber slow. I think the custom scrollbar is the leading cause. Ugh.

EDIT #2: The live code is a spaghetti of setTimeouts. I tried to lazy load the scroll pane but its still too sluggish for IE.


To make the IE script is too slow message dissapear you need to use more setTimeout. The problem is hitting 5 million javascript commands. setTimeout resets this counter.

Replacing the accordion calls

$(this).accordion({
    ...
});

With

var that = this;
setTimeout(function() {
    $(that).accordion({ ... });
}, 0);

Should fix your problem. It won't speed up the code though, it will just make the script is too slow dissapear.

As for actual optimisation there are two obvouis things.

Instead of $('.room:eq(0)')

Use $(".room").eq(0)

Edit

.each(function() {
    setTimeout(function() {
        ...
    }, 0);
}


I haven't gone and tried this myself in your case, but in my experience with these things here's what order I'd consider your refactorings.

Since that error is due to JS executing for 10 seconds straight or more, I'd focus on that and not on optimizing the HTML or GZip or even image loading. IMO your problem is all of the JS execution setting up the accordions and possibly the slightly expensive selectors. I don't think it's because you're loading 31k of JSON. It's the processing of it all that's killing you.

Delaying each iteration of $('#roomz .room-accordion').each(function() {...} by 100ms or so is what I'd focus on first, so do #1.

You also might consider changing all of the ":eq(0)" parts of your selectors to ":first" unless there is some clever reason I don't understand to use that exact selector.

Hope that helps, even though I don't have the exact code tweaks you should apply.

0

精彩评论

暂无评论...
验证码 换一张
取 消