Raphael.js导致"强制同步布局"瓶颈

Kat*_*tie 1 javascript jquery raphael

我用chrome(使用时间轴)监控了我的站点的页面加载时间,并且收到了数百条警告,表示所有Raphael.js调用的"强制同步布局是一个可能的性能瓶颈":

在此输入图像描述

我不知道如何解决这个问题:/

关于在哪里看的任何想法?

这是我通常在页面上创建文本的方式:

currentPaper.text(width,height,"text")
            .attr({opacity:.8, fill: "#333", 'font-size':10})
            .id = "someId";

//Or, to be exact:

currentPaper.text(x_pos+(width/2), 
                  y_pos-height/8, 
                  lopaLayoutArray.x[s].y1[r].y2[x])
            .attr({opacity:.8, fill: "#333", 'font-size':(10*size)})
            .id = seatName+"-textLabel";
Run Code Online (Sandbox Code Playgroud)

谢谢!

Kat*_*tie 6

问题:

这个问题被称为" 布局抖动 ",并且正在发生,因为浏览器试图在每次拉斐尔绘图后立即刷新/重绘.

例如,这会导致布局颠簸:

var a = document.getElementById('element-a');
var b = document.getElementById('element-b');

a.clientWidth = 100;
var aWidth = a.clientWidth;

b.clientWidth = 200;
var bWidth = b.clientWidth;
Run Code Online (Sandbox Code Playgroud)

"在这个简单的例子中,浏览器将更新整个布局两次.这是因为在设置第一个元素的宽度后,你要求检索一个元素的宽度.当检索css属性时,浏览器知道它需要更新的数据,所以它然后继续更新内存中的整个DOM树.只有这样,它才会继续到下一行,由于相同的原因,这将很快导致另一次更新."

这可以通过改变代码的顺序来解决,如下所示:

var a = document.getElementById('element-a');
var b = document.getElementById('element-b');

a.clientWidth = 100;
b.clientWidth = 200;

var aWidth = a.clientWidth;
var bWidth = b.clientWidth;
Run Code Online (Sandbox Code Playgroud)

"现在,浏览器将一个接一个地更新这两个属性而不更新树."

资料来源:

https://blog.idrsolutions.com/2014/08/beware-javascript-layout-thrashing/

http://www.codeproject.com/Articles/758790/Debugging-and-solving-the-Forced-Synchronous-Layou

http://www.stubbornella.org/content/2009/03/27/reflows-repaints-css-performance-making-your-javascript-slow/

https://dev.opera.com/articles/efficient-javascript/?page=3#reflow

灵魂:

修复此问题的一种方法(一种非常快速和肮脏的方式)是隐藏()你正在绘制的div,然后,当你完成时,show()它.我和拉斐尔在这方面有过一次成功和失败的结果,而且这种方式一直很奇怪.但是快...

"当一个元素的显示样式设置为none时,即使它的内容被更改,也不需要重新绘制,因为它没有被显示.这可以作为一个优点使用.如果需要对一个元素进行多次更改.元素或其内容,并且不可能将这些更改组合成单个重绘,元素可以设置为display:none,可以进行更改,然后可以将元素设置回其正常显示.

结果如下:

在此输入图像描述

这种方式对我有用!