在样式化DOM上使用$ .before()的性能问题

时间:2016-04-23 14:14:06

标签: javascript jquery html5

我遇到了一个有趣的问题,可能与浏览器有关(但我对此并不确定)。我正在开发一个非常大的网页,这是一个文字处理器风格的应用程序。我有这个结构:

<article>
    <div>...</div>
    <div>...</div>
    <div>...</div>
    ... 5000 more divs ...
</article>

当我第一次加载页面时,我有一个功能可以完成两件事。首先,它使用正则表达式分析每个div的html的内容,如果它匹配特定的正则表达式,则将一个类应用于div,结果如下:

<article>
    <div class="type1">...</div>
    <div class="type2">...</div>
    <div class="type3">...</div>
    ... 5000 more divs ...
</article>

然后函数的第二部分计算每个div的高度并将其添加到计数器。一旦它通过一定数量,我插入一段HTML作为分页符,然后冲洗并重复:

    // Pagination variables
    var document_current_page_height = 0;
    var constant_default_page_height = 1000;
    var page_number = 0;

    // Iterate over page elements
    object_range.each(function()
    {    
        // Check whether page is too long
        if (document_current_page_height + $(this).outerHeight(true) > constant_default_page_height) 
        {
            // Create page break
            $(this).before("<section contenteditable=\"false\"><h3 class=\"page-footer\">" + document_page_footer" + "</h3><figure><hr /><hr /></figure><h1 class=\"page-header\">" + document_page_header + "</h1><h2 class=\"page-number\">" + page_number + "</h2></section>");

            // Adjust variables
            page_number++
            document_current_page_height = 0;
        }

        // Increment current page height
        document_current_page_height += $(this).outerHeight(true));
    });

此代码完美无缺,但问题在于......

当它应该运行时运行时,大约需要2秒钟。但是,如果我运行相同的代码,但跳过进程的第一部分(将类添加到div),代码将在0.2秒内运行。

我还能通过评论$(this).before代码行来隔离问题。完成后,两个速度测试都足够相同(在100毫秒内)。

我不能得到的是,$(this).before代码行没有引用div的高度/样式/类,那么为什么div有一个类的延迟呢?

这只是一个浏览器在有课程时与div斗争的情况吗?有什么想法吗? (我使用的是Safari 9.1)。

谢谢!

1 个答案:

答案 0 :(得分:0)

我找到了解决问题的方法,但实际上并没有解决浏览器行为异常的原因......

我没有使用$(this).before,而是将相关的$(this)添加到一个普通的JS array中,然后在之后调用:

// Pagination variables
var document_current_page_height = 0;
var constant_default_page_height = 1000;
var page_number = 0;
var page_break_array = [];

// Iterate over page elements
object_range.each(function()
{    
    // Check whether page is too long
    if (document_current_page_height + $(this).outerHeight(true) > constant_default_page_height) 
    {
        // Create page break
        page_break_array.push([$(this), page_number]);

        // Adjust variables
        page_number++
        document_current_page_height = 0;
    }

    // Increment current page height
    document_current_page_height += $(this).outerHeight(true));
});

// Create page breaks (done separately for performance benefit)
for (var i = 0; i < page_break_array.length; i++) { page_break_array[i][0].before("... HTML content ..."); }