Jquery columnizer插件:在Windows Firefox中快40倍。为什么?

时间:2013-11-01 23:05:29

标签: javascript jquery firefox browser

我有很多大型文本,我正在使用一个轻度精简版的columnizer jquery插件(https://github.com/adamwulf/Columnizer-jQuery-Plugin)转换成“列”以便在另一个插件中使用。就我的目的而言,Columnizer是一个好的表现者 - 只要列中没有浮动的内容。

Chrome,FF和IE10在纯文本或文字上都有相似的表现,图像和其他简单的html混合在一起。但是,如果您包含浮动内容(在这种情况下是图像),则情况会发生巨大变化:

Big Book w/ Images, roughly 700 columns created
Test condition                      Firefox (sec)    Chrome (sec)
-----------------------------------------------------------------
Normal book build (images, floats)        31.5         1254.2
As above, but no images                   23.2           18.9
w/ images, but no floated images          25.1           24.7
Only a few floated images                 27.6         1010.9
Remove all images, tags except 'p'        21.3           18.9

正如您所看到的,这是一个巨大而巨大的差异。 (我确实缓存了构建版本,但由于每个浏览器/操作系统组合的呈现方式略有不同,我仍然必须先在“主要”浏览器中构建每个版本。直到你在iPad上等待Safari来构建它事情 - 将windows chrome数字乘以4。)

所以我的问题: firefox正在做什么“正确”而没有被问到,我该怎么做才能重新使用列化器代码来模仿其他浏览器呢? Columnizer相当“脏” “因为它有成千上万(我认为在本书的情况下超过10万)的追加,我知道这绝对不是酷。它是否使用文档片段?其他一些技巧?

Columnizer要求目标容器(它执行其内容流的位置)在dom中,以便可以正确应用样式(即,没有“display:none”,然后在完成时切换)。在我的CSS中,我将其设置为position:absolute,visibility:hidden,如建议的那样。我认为FF必须以其他浏览器不支持的方式查看这组属性。还是...?

我应该注意在这个过程的最后,除了轻微的字体渲染差异外,浏览器的输出是相同的。

1 个答案:

答案 0 :(得分:0)

我并不完全确定这个回答我自己的问题,但我确实做得更好,这在某些方面对我来说足够了。 我很想知道为什么我的解决方案有所不同。

背景:我尽可能多地在PHP中“预格式化”本书的文本,因为在服务器端进行清理和其他平凡的文本工作要快得多。这个清理好的html块然后被抛入div中,这就是我的列。这个容器(我们称之为“raw”),以及列(“dest”)的空目标容器需要在dom中,所以我在包装div上有这个CSS,它有“raw”和“dest”作为孩子:

position: absolute; 
top: -2000px;
left: -2000px;
width: 700px;
height: 500px;
visibility: hidden; 
overflow: hidden;

这个“删除了”页面中的两个div(就我们的眼球而言),但它们仍然在dom中,允许Columnizer与它们一起工作。

嗯:在Firefox中,这足以让事情顺利进行,浮动或不行。但是在Chrome,Safari和IE中......好吧,请看我原来问题中的表格。呸。

但是通过将“position:absolute”添加到“raw”,其他浏览器的性能显着提高。它们没有FF那么快,但也不甘落后。而不是1200多秒,Chrome现在需要40秒才能看完整本书。 ipad,而不是冰川时代,需要几分钟。

为什么呢?这对我来说是一个谜。在准备过程中,这似乎是列化器中的相关位:

...
var $sourceHtml = $('div.raw'),
    $cache      = $('<div></div>'),
    $inBox      = $('#dest'),
    $destroyable, $col;
...
$cache.append($sourceHtml.contents().clone(true));
$inBox.empty();
$inBox.append($("<div style='width:" + options.width + "px;'></div>")); 
$col = $inBox.children(":last");
$inBox.empty();
try {
    $destroyable = $cache.clone(true);
} catch(e) {
    $destroyable = $cache.clone();
}
...

作为缓存创建的空div应该在DOM中,但此时在HTML页面之外,因为它尚未附加到任何内容。嗯?因此,在操作时,页面不需要重新绘制。

我的半诅咒理论是,虽然FF认识到,其他浏览器没有,并认为$ destroyable在页面的绘制区域内 - 可能将其附加到body标签或甚至“换行” (虽然通过Chrome的检查员观看没有显示这样的事情)?

当节点从$ destroyable中剥离并附加到正在创建的列时,其他浏览器会在每次更改$ destroyable时重新绘制页面。使用块和内联材料快速,添加浮动时价格昂贵。

但要在这个半生不熟的想法中挖出一个漏洞:试图将“position:absolute”添加到$ destroyable没有任何区别。只有当原始的“原始”div具有该属性时才会加速。

无论如何,回到沉重的饮酒和无知。如果可以的话,请耐心地叹一口气,让这个成为可教的时刻!