如何在更新许多元素时阻止IE重绘

时间:2013-06-04 22:35:58

标签: javascript performance internet-explorer-10

我有一个页面,其中包含许多以网格布局的div。每个div都有文本。我希望文本足够大以填补div。我这样做是通过增加文本大小直到我检测到div已经滚动,然后返回,根据这个答案:

Auto-size dynamic text to fill div

这在大多数浏览器上都很有效,包括移动浏览器,但在IE10上它非常慢。你可以实际观察它使文字变小。我猜测每次字体大小改变时它都会进行某种窗口范围的布局操作。

知道如何暂停重绘,直到完成所有div或以其他方式提高性能?

这是一个显示该技术的简单小提琴。想象一下,页面上有大约50个div。立即使用Chrome浏览器,在IE10中需要几秒钟:

(function($) {
$.fn.textfill = function(options) {
    var fontSize = options.maxFontPixels;
    var ourText = $('span:visible:first', this);
    var maxHeight = $(this).height();
    var maxWidth = $(this).width();
    var textHeight;
    var textWidth;
    do {
        ourText.css('font-size', fontSize);
        textHeight = ourText.height();
        textWidth = ourText.width();
        fontSize = fontSize - 1;
    } while ((textHeight > maxHeight || textWidth > maxWidth) && fontSize > 3);
    return this;
}
})(jQuery);

$(document).ready(function() {
    $('.jtextfill').textfill({ maxFontPixels: 200 });
});

jsfiddle:http://jsfiddle.net/pRJdY/

2 个答案:

答案 0 :(得分:0)

jsFiddle失败,因为jQuery jsFiddle引用的版本中存在一个错误http://bugs.jquery.com/ticket/13980

所以我创建了一个本地版本的示例。我想我看到你在谈论什么,但并不完全确定。我看到它从正常的小文本变得更大,但它发生得非常快。我在Chrome中看到了相同的行为。所以我的猜测是,直到我在页面上有数千个元素,我可能无法重新创建您的问题。

我确实优化了你的JavaScript,所以我希望能帮你解决一下:

(function ($) {

            $.fn.textfill = function (options) {

                var $this = $(this),
                    fontSize = options.maxFontPixels,
                    ourText = $('span:visible:first', this),
                    maxHeight = $this.height(),
                    maxWidth = $this.width(),
                    textHeight,
                    textWidth;

                do {
                    ourText.css('font-size', fontSize);
                    textHeight = ourText.height();
                    textWidth = ourText.width();
                    fontSize = fontSize - 1;
                } while ((textHeight > maxHeight || textWidth > maxWidth) && fontSize > 3);

                return this;

            }

        })(jQuery);

答案 1 :(得分:0)

问题是大量的DOM访问。幸运的是,您的算法可以大大优化。

从200px fontsize开始下降,当你最终以10-30px结束时非常慢。最好上去,更好地进行二进制搜索以获得正确的大小。

从最小尺寸开始,上升速度提高5倍,在这种情况下,至少:http://jsfiddle.net/pRJdY/2/

二进制搜索再次将所需时间缩短一半:http://jsfiddle.net/pRJdY/4/

(function($) {
$.fn.textfill = function(options) {
    var start = (new Date).getTime(),
        node = $(this),
        max = options.maxFontPixels,
        min = 3,
        span = $('span:visible:first', this),
        maxHeight = node.height(),
        maxWidth = node.width(),
        size,
        isTooBig,
        finalSize = null;

    do {
        console.log(size);
        size = Math.round((min + max) / 2);
        span.css('font-size', size);
        isTooBig = (span.height() > maxHeight || span.width() > maxWidth);
        if (isTooBig) {
            max = size - 1;
        } else {
            min = size;
        }
        if (min === max) {
            finalSize = max;
        }
    } while (finalSize === null);

    span.css('font-size', finalSize);

    console.log('elements:', node.size(), 'elapsed time:', (new Date).getTime() - start);
    return this;
}
})(jQuery);