使用.html(字符串)的Jquery速度真的很慢,我怎样才能加快速度呢?

时间:2011-05-28 04:09:45

标签: javascript jquery optimization

我的功能平均需要250毫秒才能完成。我希望在更短的时间内完成这项工作,如果我能够<10毫秒,那么<20毫秒。

function updateDisplay() {
    var start = new Date().getTime();
    var $this = $(this);
    var data = $this.data('ansi');
    var html = '';
    for (var i = 0; i < data.screen.length; i++) {
        for (var j = 0; j < data.screen[i].length; j++) {
            html += data.screen[i][j];
        }
        html += '<br />';
    }
    var create = new Date().getTime();
    console.log('Build html: ' + (create-start));
    $this.html(html);
    var end = new Date().getTime();
    console.log('Update html: ' +(end-create));
}

我在setInterval侧调用此函数来更新我的显示,每帧构建html字符串为0ms到1ms,但更新html在100ms到300ms之间。反正有没有让它更快?

Bah,打开Chrome检查员观看控制台是否会增加一个巨大的延迟 这是我目前的功能(基本上是从CD Sanchez下降)。没有检查员打开它在大约50ms运行更新html。这要好得多,但如果可以的话,我希望能达到<20ms。

function updateDisplay() {
    var start = new Date().getTime();
    var $this = $(this);
    var data = $this.data('ansi');
    var html = Array();
    for (var i = 0, length1 = data.screen.length; i < length1; ++i) {
        var a = data.screen[i]; // cache object
        for (var j = 0, length2 = a.length; j < length2; ++j) {
            html.push(a[j]); // push to array
        }
        html.push('<br />');
    }
    var create = new Date().getTime();
    this.innerHTML = html.join(''); // use innerHTML
    var end = new Date().getTime();
    $('#debug').html('Build html: ' + (create-start) + '<br/>Update html: ' + (end-create));
}

html的示例值 - 第1行,最多<br>

<span style="background-color:#000000;color:#ffffff;">&nbsp;</span><span style="background-color:#000000;color:#ffffff;">&nbsp;</span><span style="background-color:#000000;color:#ffffff;">&nbsp;</span><span style="background-color:#000000;color:#ffffff;">&nbsp;</span><span style="background-color:#000000;color:#ffffff;">&nbsp;</span><span style="background-color:#000000;color:#ffffff;">&nbsp;</span><span style="background-color:#000000;color:#ffffff;">┌</span><span style="background-color:#000000;color:#ffffff;">─</span><span style="background-color:#000000;color:#ffffff;">─</span><span style="background-color:#000000;color:#ffffff;">─</span><span style="background-color:#000000;color:#ffffff;">─</span><span style="background-color:#000000;color:#ffffff;">─</span><span style="background-color:#000000;color:#ffffff;">─</span><span style="background-color:#000000;color:#ffffff;">─</span><span style="background-color:#000000;color:#ffffff;">─</span><span style="background-color:#000000;color:#ffffff;">─</span><span style="background-color:#000000;color:#ffffff;">─</span><span style="background-color:#000000;color:#ffffff;">─</span><span style="background-color:#000000;color:#ffffff;">─</span><span style="background-color:#000000;color:#ffffff;">─</span><span style="background-color:#000000;color:#ffffff;">─</span><span style="background-color:#000000;color:#ffffff;">─</span><span style="background-color:#000000;color:#ffffff;">─</span><span style="background-color:#000000;color:#ffffff;">─</span><span style="background-color:#000000;color:#ffffff;">─</span><span style="background-color:#000000;color:#ffffff;">─</span><span style="background-color:#000000;color:#ffffff;">─</span><span style="background-color:#000000;color:#ffffff;">─</span><span style="background-color:#000000;color:#ffffff;">─</span><span style="background-color:#000000;color:#ffffff;">─</span><span style="background-color:#000000;color:#ffffff;">─</span><span style="background-color:#000000;color:#ffffff;">─</span><span style="background-color:#000000;color:#ffffff;">─</span><span style="background-color:#000000;color:#ffffff;">─</span><span style="background-color:#000000;color:#ffffff;">─</span><span style="background-color:#000000;color:#ffffff;">─</span><span style="background-color:#000000;color:#ffffff;">─</span><span style="background-color:#000000;color:#ffffff;">─</span><span style="background-color:#000000;color:#ffffff;">─</span><span style="background-color:#000000;color:#ffffff;">─</span><span style="background-color:#000000;color:#ffffff;">─</span><span style="background-color:#000000;color:#ffffff;">─</span><span style="background-color:#000000;color:#ffffff;">─</span><span style="background-color:#000000;color:#ffffff;">─</span><span style="background-color:#000000;color:#ffffff;">─</span><span style="background-color:#000000;color:#ffffff;">─</span><span style="background-color:#000000;color:#ffffff;">─</span><span style="background-color:#000000;color:#ffffff;">─</span><span style="background-color:#000000;color:#ffffff;">─</span><span style="background-color:#000000;color:#ffffff;">─</span><span style="background-color:#000000;color:#ffffff;">─</span><span style="background-color:#000000;color:#ffffff;">─</span><span style="background-color:#000000;color:#ffffff;">─</span><span style="background-color:#000000;color:#ffffff;">─</span><span style="background-color:#000000;color:#ffffff;">─</span><span style="background-color:#000000;color:#ffffff;">─</span><span style="background-color:#000000;color:#ffffff;">─</span><span style="background-color:#000000;color:#ffffff;">─</span><span style="background-color:#000000;color:#ffffff;">─</span><span style="background-color:#000000;color:#ffffff;">─</span><span style="background-color:#000000;color:#ffffff;">─</span><span style="background-color:#000000;color:#ffffff;">─</span><span style="background-color:#000000;color:#ffffff;">─</span><span style="background-color:#000000;color:#ffffff;">─</span><span style="background-color:#000000;color:#ffffff;">─</span><span style="background-color:#000000;color:#ffffff;">─</span><span style="background-color:#000000;color:#ffffff;">─</span><span style="background-color:#000000;color:#ffffff;">─</span><span style="background-color:#000000;color:#ffffff;">─</span><span style="background-color:#000000;color:#ffffff;">─</span><span style="background-color:#000000;color:#ffffff;">─</span><span style="background-color:#000000;color:#ffffff;">─</span><span style="background-color:#000000;color:#ffffff;">┐</span><span style="background-color:#000000;color:#ffffff;">&nbsp;</span><span style="background-color:#000000;color:#ffffff;">&nbsp;</span><span style="background-color:#000000;color:#ffffff;">&nbsp;</span><span style="background-color:#000000;color:#ffffff;">&nbsp;</span><span style="background-color:#000000;color:#ffffff;">&nbsp;</span><span style="background-color:#000000;color:#ffffff;">&nbsp;</span><span style="background-color:#000000;color:#ffffff;">&nbsp;</span><br>

示例 - here,目前仅在Chrome中测试过。已知在IE中工作的结......

更新 我已将我的代码转换为使用画布并直接绘制。我不确定我是否是最好的方式,因为它是我第一次使用画布。现在看,我大约20ms。那就是我高兴的地方的上端,虽然10ms会更好。

我不确定我是否可以在样式中定义前景色和背景色并删除fillRect来电,如果可以的话,这会加快速度。另一个问题是字体看起来不像纯html那样清晰,不确定我是否能解决这个问题。上面链接的示例已更新。

function updateDisplay() {
    var start = new Date().getTime();
    var $this = $(this);
    var data = $this.data('ansi');
    for (var i = 0, length1 = data.screen.length; i < length1; ++i) {
        var a = data.screen[i]; // cache object
        for (var j = 0, length2 = a.length; j < length2; ++j) {
            data.ctx.fillStyle = a[j][0];
            data.ctx.fillRect (8*j, 14 * i, 8, 14);
            data.ctx.fillStyle = a[j][1];
            data.ctx.fillText(a[j][2], 8*j, 14 * i);
        }
    }
    var end = new Date().getTime();
    $('#debug').html('Frame Time: ' + (end-start));
}

上次更新 ctx.fillText非常慢,而且不够准确,不适合我的目的。我已将自己的字体定义为8x16数组,并使用ctx.fillRect绘制每个像素。这要快得多,并处理它接缝的字体子系统。

4 个答案:

答案 0 :(得分:1)

以下是一些非常小的优化,我怀疑它会有多大帮助,但无论如何你都去了:

function updateDisplay() {
    var start = new Date().getTime();
    var $this = $(this);
    var data = $this.data('ansi');
    var html = [];
    for (var i = 0, length1 = data.screen.length; i < length; ++i) {
        var a = data.screen[i]; // cache object
        for (var j = 0, length2 = a.length; j < length2; ++j) {
            html.push(a[j]); // push to array
        }
        html.push('<br />');
    }
    var create = new Date().getTime();
    console.log('Build html: ' + (create-start));
    this.innerHTML = html.join(''); // use innerHTML
    var end = new Date().getTime();
    console.log('Update html: ' +(end-create));
}

当然,这些只是简单的JavaScript优化(在较新的浏览器中并不是那么有用)。听起来你需要简化HTML和可能的CSS,以便HTML引擎可以更快地渲染它。

答案 1 :(得分:1)

为了理解这类问题,我发现Dynatrace Ajax Edition是最好的工具,因为它还可以告诉渲染花费了多少时间,而不仅仅是javascript执行。可能还有其他类似的工具我觉得这个很好。

我想您可能想重新考虑整个方法。编写HTML元素来创建动画永远不会是一个好的理念。这就是我们有像canvas,svg和flash / silverlight这样的东西的原因。有可能在某种程度上进行优化,但请使用正确的工具。也许不是你想要的答案,但我认为如果你使用画布或svg,你会对性能以及可维护性感到更满意。

http://raphaeljs.com/reference.html#text是一个不错的图书馆

更新1: 如果你真的想这样做,我会尝试改变方法。现在你每次重绘整个“网格”。看动画看起来你应该每次只能更新一行。我认为你可以将每行包裹在div中,而对于每一帧,你只需要重写该行上div的内容。我会在数组中存储对div的引用,这样就可以避免在每个帧上运行选择器。

答案 2 :(得分:0)

尚未经过测试,但假设join是一个字符串数组,那么使用data.screen[i]函数可能会加快速度,但是

(循环)

for (var i = 0; i < data.screen.length; i++) {
        html += data.screen[i].join("");
    html += '<br />';
}

Concat'字符串可能看起来像一个简单的添加,但每次使用+=时都会创建一个新的字符串对象。我建议使用类似StringBuffer的内容。

编辑:

好的,在您的示例代码中,您尝试每隔几毫秒替换数千行html,每次只更改一个字符。如果您每次只更改一个字符,则可以将延迟减少~99%

答案 3 :(得分:0)

您确定问题是实际附加数据而不是呈现数据吗?如果你的标记很复杂(很多span可能是,取决于有多少),那么新标记的渲染时间是不可忽略的。如果您将通话更改为.html(html).text(html),会发生什么情况?

我不是建议您将此作为最终修复(text不解析HTML标记),但它可以帮助您查看是否需要渲染或追加时间。