高性能Javascript的重排和重绘(2)

高性能Javascript的重排和重绘(2)
The first to review the previous articles of high performance Javascript DOM programming, mainly made two optimization, the first is to minimize the DOM access, and the operation on the end of the ECMAscript, the two is to cache the local variables, such as length and so on, finally introduces two new API (querySelector) and querySelectorAll (in). 当你的投资组合可以大胆使用。本文的主要观点是,DOM编程可能是最耗时的,重排和重绘。
1。重排和重绘是什么

下载页面中的所有组件——HTML标记、Javascript、CSS和图像之后,浏览器将分析并生成两个内部数据结构——DOM树和呈现树。

DOM树表示页面结构,而呈现树指示DOM节点如何显示。在绘制树种至少一个对应的节点(隐藏的DOM元素的显示值是没有的,有没有相应的渲染树节点)。在渲染树中的节点被称为框架或框一旦建立了DOM和渲染树,浏览器开始显示(画)页面元素。

当DOM的变化影响要素的几何属性(宽和高),浏览器需要重新计算元素的几何性质。同样,几何性质和其他元素的位置也会受到影响。浏览器将失效的渲染树患处并重组渲染树。这一过程称为重排,重排后完成,浏览器重新绘制到屏幕,即重画。因为浏览器流布局,在渲染树的计算通常只需要遍历就可以完成。但是,除了表和其内部的元素,它可能需要多次计算在渲染树中的节点的属性。它通常是相同元素的3倍,这也是我们不想使用表作为布局的原因

并非所有DOM更改都会影响几何属性。例如,改变元素的背景色不会影响元素的宽度和高度。在这种情况下,重新粉刷只会发生。

2、重排和重绘的费用是多少

重新安排和调整的成本是多少让我们回到那边那座桥的例子。小心,你可能会发现一千倍的时差不是因为过桥造成的。每一座桥实际上是伴随重排和重绘,和能源消耗的绝大部分是在这里。
var时间= 15000;

每座桥+ + / /代码重排重绘
(1)console.time;
对于(var i = 0;i <次数;i + +){
document.getelementbyid('mydiv1).innerHTML = A;
}
(1)console.timeend;

只有桥 / /代码2
(2)console.time;
var=;
对于(var i = 0;i <次数;i + +){
var tmp = document.getelementbyid('mydiv2InnerHTML);
STR = A;
}
document.getelementbyid('mydiv2).innerHTML = str;
Console.timeEnd (2);

/ /代码
(3)console.time;
无功_str =;
对于(var i = 0;i <次数;i + +){
_str = A;
}
document.getelementbyid('mydiv3).innerHTML = _str;
(3)console.timeend;
1: / / 2874.619ms
2: / / 11.154ms
3: / / 1.282ms
数据不会说谎,看,多访问DOM的重排和重绘,耗费时间,简直是不值得一提。

三.重排发生在什么时候

显然,每个重组将不可避免地导致重绘,那么在什么情况下会发生重排

1,添加或删除可见的DOM元素

2。元素位置变化

3,元素大小变化

4。元素内容更改(例如,文本被另一个不同大小的图像替换

5。页面呈现初始化(这是无法避免的)

6。浏览器窗口的大小变化

这些都是很明显的,你可能有过这样的经历,不断地改变浏览器窗口的大小,从而在界面反应迟钝(IE低版本甚至直接挂),现在你可以看到光突然,是的,这是一个时间来重绘的重排!

4。呈现树变化的队列和刷新

考虑下面的代码:
无功电= document.getelementbyid('mydiv);
ele.style.borderleft = '1px;
ele.style.borderright = '2px;
ele.style.padding = '5px;
乍一想,风格的元素已经改了三次,每一个变化将导致重排和重绘,所以总共有三次重绘重排过程,但是浏览器不是那么愚蠢,它将三修正案(通过队列变化和批处理执行优化重组的过程是最节省浏览器)。完成!然而,有时您可能(常常不自觉地)强制队列刷新并要求立即执行计划的任务

1.offsettop,offsetleft,offsetwidth,offsetheight

2.scrolltop,scrollLeft,scrollwidth,scrollheight

3.clienttop,clientleft,clientwidth,自己

4.getcomputedstyle()(currentstyle伊江)

修改上面的代码一点:

无功电= document.getelementbyid('mydiv);
ele.style.borderleft = '1px;
ele.style.borderright = '2px;

使用offsetheight / /这里

ele.style.padding = '5px;

因为offsetheight属性返回新的布局信息,所以浏览器要进行处理来改变渲染队列触发重排返回正确的值(即使改变风格的属性和属性值的队列并没有想得到什么,在上面的代码),在手术前两次将缓存在渲染队列,但是当offsetheight属性请求,队列将立即执行,所以总共有两倍的重排和重绘,所以尽量不要让查询布局信息改变时。

5、尽量减少重排和重绘

让我们看看上面的代码:
无功电= document.getelementbyid('mydiv);
ele.style.borderleft = '1px;
ele.style.borderright = '2px;
ele.style.padding = '5px;
三样式属性的改变,都会影响到结构构件的几何,虽然大多数现代浏览器进行了优化,只会造成一个重排,但如上所述,如果请求的时间属性,它会强制刷新队列,这个代码四访问DOM,一个明显的策略是优化他们的合成时间的操作,这只会修改DOM:
无功电= document.getelementbyid('mydiv);

重写样式 1。
ele.style.csstext = 'border-left:1px;边框右:2px;填充:5px;;;

2。添加样式
ele.style.csstext = 'border' -;EFT:1px;

三.使用类
ele.classname =活动;
6和片断元素的应用

查看下面的代码并考虑一个问题:
苹果
橙色
如果在代码中添加桃子和西瓜两个选项,你会怎么做

VaR LIS = document.getelementbyid('fruit);
Var Li = document.createelement(李的);
li.innerhtml = 'apple;
lis.appendchild(李);

Var Li = document.createelement(李的);
li.innerhtml = 'watermelon;
lis.appendchild(李);

很容易想到这些代码,但很明显,它被重新安排了两次。你怎么把它弄坏的正如我们前面提到的,隐藏元素不在呈现树中。那太好了。我们可以先隐藏ID元素的UL元素,然后添加LI元素,最后显示出来,但是实际操作中可能会出现闪烁,这也是很容易理解的。此时,片段元素正在使用中。

var = document.createdocumentfragment(片段);

Var Li = document.createelement(李的);
li.innerhtml = 'apple;
fragment.appendchild(李);

Var Li = document.createelement(李的);
li.innerhtml = 'watermelon;
fragment.appendchild(李);

document.getelementbyid('fruit)。AppendChild(片段);

一个文档片段是一个轻量级的文档对象,目的是完成这种任务的更新和移动节点的文档片段方便的语法特征是,当你添加一个片段,一个节点,它实际上是添加到该片段的子节点,而不是片段本身。只有一个重排触发,和只有一个真正的DOM访问。

7,将元素从动画流中删除

在展开/折叠的方式中显示和隐藏部分页面是一种常见的交互模式,它通常包括动画的几何区域扩展,以及页面的其他部分到底部。

总的来说,重排只影响渲染树的一小部分,但它也能影响很大一部分,甚至整个渲染树。这个时代的浏览器需要重排数量少,更快的应用程序将响应。因此,当在页面的顶部动画通过页面的剩余的一部分,这将导致一个昂贵的大规模的重组,这会让用户感觉的一页。更多的节点在渲染树需要被重新计算,情况会更糟。

可以使用以下步骤避免页面中的大部分重排:

使用绝对位置来定位页面上的动画元素,并将其保留在文档流之外。

让元素移动。当它扩大,一些页面将被暂时掩盖,但这只是一个调整过程的一个小区域的页面,而不产生重排和重绘大多数网页的内容。

在动画结束时还原位置,使文档的其他元素只移动一次。

总结

重排和重绘在DOM编程对能源消耗的主要原因之一。在平时,以下几点可以参考DOM编程。

当更改布局信息时,不要尝试查询(这将导致对呈现队列的强制刷新)

可以将同一DOM的多个属性更改一起写入(减少DOM访问,同时减少强制呈现队列到0的风险)

如果要批量添加DOM,可以先将文档从文档流中分离出来,然后在操作之后将其引入文档流,这只会触发重新排列。(片段元素的应用)。

需要多次重新排列的元素,位置属性设置为绝对或固定,这样元素与文档流分离,其变化不会影响其他元素。例如,具有动画效果的元素最好设置为绝对位置。

以上是高性能Javascript的重排和重绘的全面介绍,你可以与以前的高性能Javascript DOM编程学习(1)。

我希望这两篇文章能帮助你解决这个领域的疑惑。
免责声明:本网信息来自于互联网,目的在于传递更多信息,并不代表本网赞同其观点。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,并请自行核实相关内容。本站不承担此类作品侵权行为的直接责任及连带责任。如若本网有任何内容侵犯您的权益,请及时联系我们,本站将会在24小时内处理完毕。
相关文章
返回顶部