javascript - Jquery 列生成器插件 : 40 times faster in Windows Firefox. 为什么?

标签 javascript jquery firefox browser

我有许多大文本,我正在使用列分析器 jquery 插件 ( https://github.com/adamwulf/Columnizer-jQuery-Plugin ) 的轻微精简版本将其转换为“列”以在另一个插件中使用。对于我的目的来说,Columnizer 是一个不错的执行者——只要被列化的 block 中没有 float 内容。

Chrome、FF 和 IE10 在大多数情况下在纯文本或混合有图像和其他简单 html 的文本上都有相似的性能。但是,如果您包含 float 内容(在本例中为图像),情况就会发生巨大变化:

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 做了什么“正确”的事情,我可以做什么来重新编写列生成器代码以在其他浏览器中模仿它? 列生成器相当“肮脏” ” 因为它执行了数千个(我认为在本书中超过 100,000 个)附加,我知道这绝对不酷。是否使用文档片段?还有其他技巧吗?

Columnizer 要求目标容器(内容流动的地方)位于 dom 中,以便可以正确应用样式(即,没有“display:none”,然后在完成后进行切换)。在我的 CSS 中,我按照建议将其设置为position:absolute、visibility:hidden。我认为 FF 必须以其他浏览器不采用的方式查看这组属性。或者...?

我应该在该过程结束时注意到,除了轻微的字体渲染差异外,浏览器之间的输出是相同的。

最佳答案

我不确定这回答了我自己的问题,但我确实让事情变得更好,这在某些方面对我来说已经足够了。 我很想真正了解为什么我的解决方案会产生影响。

背景:我尽可能多地用 PHP 对本书的文本进行“预格式化”,因为在服务器端进行清理和其他日常文本杂务要快得多。然后将清理后的 html block 放入 div 中,这就是我列的内容。这个容器(我们称之为“raw”)和列的空目标容器(“dest”)需要位于 dom 中,所以我将这个 CSS 放在一个包含“raw”和“dest”的包装 div 上作为 child :

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

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

嗯:在 Firefox 中,这足以使事情正常运行,无论是否 float 。但在 Chrome、Safari 和 IE 中……好吧,看看我原来问题中的表格。恶心。

但是通过将“position:absolute”添加到“raw”中,其他浏览器的性能得到了显着提高。他们的速度不如FF,但也相差不远。现在,Chrome 浏览整本书只需 40 秒,而不是 1200 多秒。 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 时其他浏览器都会重新绘制页面。 block 和内联内容速度很快,添加 float 时价格昂贵。

但是要戳破这个不成熟的想法:尝试将“position:absolute”添加到 $destroyable 没有什么区别。只有当原始的“原始”div 具有该属性时,速度才会加快。

无论如何,回到酗酒和无知。如果可以的话,请耐心叹息,让这成为一个受教育的时刻!

关于javascript - Jquery 列生成器插件 : 40 times faster in Windows Firefox. 为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19736831/

相关文章:

jquery - 最接近的形式附加不起作用

javascript - 嵌入式 SVG 中的 onload 事件不调用附加脚本中的函数。范围问题?

javascript - Greasemonkey 1.0 中的 jQuery 与使用 jQuery 的网站发生冲突

php - 在 php 中回显带有参数的 javascript 函数

javascript - 如何在枚举时修改对象属性值

javascript - 在 MVC 4.0 中捆绑 javascript 文件

JavaScript 在 Mozilla Firefox 中不起作用

javascript - 为什么有些值可以通过 OR 运算符,而其他值则不能?

Php 没有返回正确的 MIME 类型

jquery - 如何使用 Rails 3 更新到 jQuery 1.7+?