提高jQuery函数的效率

时间:2009-05-22 00:59:17

标签: javascript jquery

此函数中的while语句在IE / firefox中运行速度太慢(阻止页面加载4-5秒),但在safari中运行速度很快...

它测量页面上文本的像素宽度并截断,直到文本达到理想宽度:

function constrain(text, ideal_width){

    $('.temp_item').html(text);
    var item_width = $('span.temp_item').width();
    var ideal = parseInt(ideal_width);
    var smaller_text = text;
    var original = text.length;

    while (item_width > ideal) {
        smaller_text = smaller_text.substr(0, (smaller_text.length-1));
        $('.temp_item').html(smaller_text);
        item_width = $('span.temp_item').width();
    }

    var final_length = smaller_text.length;
    if (final_length != original) {
        return (smaller_text + '…');
    } else {
       return text;
    }
}

有什么方法可以提高性能?我如何将其转换为冒泡排序功能?

谢谢!

5 个答案:

答案 0 :(得分:5)

将调用移到循环外的$(),并将其结果存储在临时变量中。除了调用.html()之外,运行该函数将是代码中最慢的函数。

他们非常努力地使库中的选择器引擎变得很快,但是与普通的javascript操作(比如在本地范围内查找变量)相比,它仍然很慢,因为它必须与dom交互。特别是如果你正在使用这样的类选择器,jquery必须遍历文档中的每个元素,查看每个类属性并在其上运行正则表达式。每个环绕循环!尽可能多地从紧密循环中获取这些东西。 Webkit快速运行它,因为它有.getElementsByClassName而其他浏览器没有.getElementsByClassName。 (尚)。

答案 1 :(得分:4)

您可以使用binary search,而不是在找到理想宽度之前删除一个字符。

答案 2 :(得分:2)

我看到问题是你不断修改循环中的DOM,通过设置temp_item的html,然后重新读取宽度。

我不知道你的问题的背景,但是从我的角度来看,尝试通过测量渲染元素来调整布局并不是一个好习惯。

也许你可以从不同的角度解决问题。截断固定宽度很常见。

其他可能性(黑客?)如果没有选择,可以使用容器元素的overflow css属性,并将...放在文本旁边的其他元素中。虽然我建议你重新考虑以你想要的方式解决问题的必要性。

雨果

答案 3 :(得分:2)

除了布列塔尼的建议之外,另一种加速算法的可能性是在文本长度上使用二进制搜索。目前,您一次将长度减少一个字符 - 这是字符串长度中的O(N)。相反,使用搜索将是O(log(N))。

粗略地说,这样的事情:

function constrain(text, ideal_width){

...

    var temp_item = $('.temp_item');
    var span_temp_item = $('span.temp_item');

    var text_len_lower = 0;
    var text_len_higher = smaller_text.length;

    while (true) {
          if (item_width > ideal)
          {
            // make smaller to the mean of "lower" and this
            text_len_higher = smaller_text.length;
            smaller_text = text.substr(0, 
                ((smaller_text.length + text_len_lower)/2));
          }
          else
          {
            if (smaller_text.length>=text_len_higher) break;

            // make larger to the mean of "higher" and this
            text_len_lower = smaller_text.length;
            smaller_text = text.substr(0, 
                ((smaller_text.length + text_len_higher)/2));
          }
          temp_item.html(smaller_text);
          item_width = span_temp_item.width();
    }

...     }

答案 4 :(得分:1)

有一点需要注意的是,每次向DOM添加内容或更改节点中的html时,页面都必须重绘,这是一项昂贵的操作。在循环之外移动任何HTML更新可能有助于加快速度。

正如其他人所提到的,你可以将调用$()移到循环外部。您可以创建对元素的引用,然后在循环中调用它上面的方法,如提到的1800信息。

如果你将Firefox与Firebug插件一起使用,那么可以通过一种很好的方式来分析代码,看看花费的时间是多少。只需点击第一个标签下的个人资料,执行操作,然后再次点击个人资料。它将显示一个表格,其中包含代码的每个部分所花费的时间。你可能会在js框架库中的列表中看到很多东西;但你也可以通过一些试验和错误来隔离它。