如何让以下代码更快?

3
我正在使用phonegap开发一个应用程序。在我的电脑上一切都运行良好,但在我的移动设备上却非常缓慢。
我认为问题出在show函数上,安卓浏览器似乎需要很长时间来隐藏和显示元素。
有什么可以改进的吗?
function show(id){
    $('.view').hide()
    //alert('show ' + id)
    $('#'+id+'View').show()
    scroll(0,0)
}


function getSoundHTML(id, myname, del){

    if (del != true){
        var imgsrc = 'plus.png'
        var f = function(){
            addToCostumSounds(id)
            alert('added to favorites')
        }
    }else{
        var imgsrc = 'minus.png'
        var f = function(){
            removeFromCostumSounds(id);
            $(this).fadeOut().next('div').fadeOut();
        }
    }

    var div = $('<div></div>').addClass('box').html(myname).css('border-color', '999999').click(function(){
        play(id)
    })
    var img = $('<img></img>').attr('src', imgsrc).addClass('sideimg').click(f)

    return $('<div></div>').append(img).append(div)
}

for(var category in categories){

    var f = function(category){
        $('#'+category+'Btn').click(function(){
                show(category)

                var categoryView = $('#'+category+'View')
                for(var key in categories[category]){
                    var div = getSoundHTML(key, categories[category][key])
                    categoryView.prepend(div)
                }
                var img = '<img src="menu.png" class="menuimg"/>'
                categoryView.prepend(img)
                categoryView.append(img)
        })
    }
    f(category)
}

HTML:

    <div class="btn" id="noBtn">no _</div>
    <div class="btn" id="thatIsBtn">that is _</div>
    <div class="btn" id="thereIsBtn">there is _</div>
    <div class="btn" id="thisIsBtn">this is _</div>
    ...


<div class="view" id="noView"></div>
<div class="view" id="thatIsView"></div>
<div class="view" id="thereIsView"></div>
<div class="view" id="thisIsView"></div>
...

2
你可以尝试先通过 JSLint(http://www.jslint.com/)运行你的代码,以便先整理一下它。 - isNaN1247
第二次阅读后:你在同一位置定义和使用f函数的原因是什么?看起来有些冗余。 - Damien Wilson
3个回答

2
虽然这可能对桌面电脑没有影响,但是您在正确位置缺少大量分号可能会影响移动设备。
JavaScript引擎必须运行并尝试确定分号应该放在哪里。请参见ECMAScript规范的此转录
老实说,我认为这只能节省几毫秒的时间,但现在它是一个起点,也是未来的好习惯。

我认为JS解析器在这方面要简单得多:一行上的1个语句=没有问题,一行上的2个语句没有分号=错误(FF 4.01也同意我的看法)。因此,根据我所见,添加或删除代码中的分号对解析器本身应该没有任何影响(实际上少读一个符号,这完全不重要)。 - Voo
@Voo - 我的回答基于 Douglas Crockford 在他关于 The Good Parts 的演讲中的评论。此外,我现在已经链接到了这个领域的规范。 - isNaN1247
我怀疑分号不是问题所在。分号也是可选的,并且我怀疑分号插入足以引起OP所描述的挂起问题。 - Damien Wilson
确实 - 我小心地指出它可能仅对移动设备产生影响。虽然可选,但最好在刚开始时不要使用懒散的做法。更新 - 刚刚阅读了您的链接,并且感谢我们在这个问题上来自不同的思想流派。 :) - isNaN1247
1
@beartwizzle:哦,我和最好的人一样使用分号,我只是指出任何现代解释器都应该处理任何情况而不会出现任何问题(无论是晦涩还是其他)。如果我决定去掉分号,JSLint会让我发疯。 - Damien Wilson

1

这是你的问题:

for(var category in categories){

    var f = function(category){
        ...
        for(var key in categories[category])
        ...
    }

    f(category)
}

你有两个大问题:

  1. 你在循环内定义了一个函数。虽然有时候需要这样做,但除非你绝对需要,否则应该尽力避免在循环内定义东西。在这种情况下,你可以完全将 f 函数移到循环外而不会破坏你的代码。
  2. 嵌套循环。你在一个 for ... in 循环内部又有一个 for ... in 循环。这主要是由我指出的第一个问题造成的,但总的来说,从性能的角度来看,嵌套循环是一个大忌。

谢谢,我将函数定义从循环中移开了。但我没有注意到任何不同。而且里面没有循环嵌套。第二个循环是在一个函数中定义的,只是被点击调用了。 - ihucos
也许我应该更多地使用静态HTML而不是用JavaScript构建它? - ihucos
@nomoral:您说得对,尽管我仍然坚持我的观点,即在几乎任何情况下都应避免使用嵌套的for ... in循环。 - Damien Wilson

0

好的,我认为我找到了唯一提高性能的方法:

如果有人单击一个按钮(class="btn"),他将被重定向到一个全新的页面,该页面是 HTML 格式的,并且不使用 JavaScript 构建。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接