【问题标题】:What can I do to optimize my ajax application for IE7/IE8 in order to avoid "Stop running this script"?为了避免“停止运行此脚本”,我可以做些什么来优化 IE7/IE8 的 ajax 应用程序?
【发布时间】:2014-08-12 20:34:24
【问题描述】:

我有一个在 IE7 中相当缓慢的预订引擎。它是基于 ajaxified 和散列/窗口 onchange 的。总共有 5 个步骤。我遇到的主要问题是第 2 步在 IE 中非常慢。

当用户进入第 2 步时,会发出一个 ajax 请求以通过 Web 服务提取数据以显示酒店房间。酒店客房分为主要房型和内部更具体的房型。应用于酒店房间的 JS 功能包括:

  • 房间里的手风琴
  • 房间类型的手风琴(嵌套手风琴)
  • 快速翻转图片
  • jscrollpane,图片翻转后左侧房间描述的自定义滚动条
  • jscrollpane,右侧房间类型的自定义滚动条

这一切都导致了著名的:

我在 Google 上搜索并登陆了 thisthisthis

很明显,原因是在 IE 中的特定时间内顺序执行的脚本语句太多。

我基本上需要重构我的代码并对其进行优化,以便在函数调用之间存在延迟。

我在执行 ajax 请求后注入 HTML 的方式是:

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

o.html 是对 JSON 对象 html 属性的引用,该属性派生自 here

然后,下面的代码运行:

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);

        });

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

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

    });



}, 20);

我的第一个版本的代码基本上将快速翻转和滚动窗格应用于每个房间,无论它是否隐藏在手风琴中。重构的版本( live/current one )将它应用到手风琴中第一个活动的房间,当通过手风琴点击另一个房间时,我将快速翻转和滚动窗格应用到它。

我在整个事情周围添加了一个 setTimeout,因为这发生在 HTML 被注入之后。我里面也有setTimeouts。

好像还是太慢了。 谁能提供任何重构/优化技巧?

我再次重构它的想法包括:

  1. 不是在.room accordion 上执行.each,而是应用重复操作来强制延迟between each iteration like this
  2. 进一步优化和缩小 ajax 返回的 HTML - 我已经做了很多优化,删除了空格,不显示 HTML cmets 等等。
  3. 启用 Gzip
  4. 对图像进行延迟加载,以便仅显示可见的手风琴内容图像,而其他图像则为 blank.gif,直到您通过手风琴激活它们为止
  5. 不是返回 HTML 并转储它,而是只返回没有 HTML 的相关数据,而是使用模板引擎构建 HTML?!

如果有人可以就我的重构想法提供意见,看看哪些想​​法会产生最佳结果,那就太好了。

链接:

  • 有问题的页面是this
  • 相关JS为here
  • 相关代码/行号从new.js的第829行开始(这是我粘贴的sn-p)
  • this page发出相关的ajax请求。

PS - 不支持 IE6

编辑:我在.each 的迭代之间设置了延迟,但它仍然非常慢。我认为自定义滚动条是主要原因。呃。

EDIT #2live code 是 setTimeouts 的意大利面。我试图延迟加载滚动窗格,但它对于 IE 来说仍然太慢了。

【问题讨论】:

  • 是的,当我写作时,我承认我比较着急,不太想在语义上正确,但你是对的。
  • 仅供任何测试的人参考,我禁用了自定义滚动条,这似乎摆脱了对话框......所以我还没有完全解决这个问题。
  • 听起来您已将其范围缩小到 jScrollPane。我猜你可以删除 setTimeouts 看看它是否仍然有效。如果是这种情况,我要么配置文件(使用 Chrome 开发工具),要么在jscrollpane.kelvinluck.com/script/jquery.jscrollpane.js 上查看 jscrollpane 的 src,看看可能会影响性能。

标签: javascript internet-explorer optimization dom refactoring


【解决方案1】:

要让IE脚本太慢消息消失,你需要使用更多setTimeout。问题是达到 500 万条 JavaScript 命令。 setTimeout 重置此计数器。

替换手风琴调用

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

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

应该可以解决您的问题。但它不会加速代码,它只会让脚本太慢消失。

至于实际的优化有两点很明显。

而不是$('.room:eq(0)')

使用$(".room").eq(0)

编辑

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

【讨论】:

  • 你确定?我将它应用于手风琴调用,对话框似乎仍然存在。
  • 然后你需要将每个块的内容包装在一个 setTimeout 中。
  • 你的意思是像我最初的样子?围绕整个.slowEach 块?会的..
  • 是的,我应用了 setTimeouts,不管在 IE7 中启用 jScrollPane 时它​​仍然太慢。
  • @meder 然后尝试使用分析器并在操作调用方面找到您的瓶颈。 IE8 开发者工具中应该有分析器(IE7 也可以)
【解决方案2】:

在您的情况下,我还没有亲自尝试过,但是根据我对这些事情的经验,这是我认为您的重构的顺序。

由于该错误是由于 JS 连续执行 10 秒或更长时间所致,因此我将重点关注这一点,而不是优化 HTML 或 GZip 甚至图像加载。 IMO 你的问题是所有的 JS 执行设置手风琴和可能稍微昂贵的选择器。我不认为这是因为您正在加载 31k 的 JSON。是对这一切的处理让你丧命。

$('#roomz .room-accordion').each(function() {...} 的每次迭代延迟 100 毫秒左右是我首先要关注的,#1 也是如此。

您还可以考虑将选择器的所有 ":eq(0)" 部分更改为 ":first" ,除非有一些我不明白的聪明理由使用那个确切的选择器。

希望对您有所帮助,即使我没有您应该应用的确切代码调整。

【讨论】:

  • 他们不是都比.eq(0)慢吗?无论如何,我在.each 和使用.eq(0) 之间添加了一个延迟。
  • 意思是添加,在每次迭代之间添加setTimeouts和setTimeout延迟后,仍然得到对话框:(
  • -1:该错误不是由于JS执行10秒或更长时间造成的。鉴于 OP 的问题与 IE7/IE8 有关,这是因为 JS 连续执行了 500 万条语句。这是一个非常重要的区别,因为它以非常重要的方式影响解决方案。 stackoverflow.com/a/2345724/109941
猜你喜欢
  • 2010-09-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-11
  • 2017-12-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多