减少重排提高性能的方式

尽管网页达到了2MB,但是性能却成了一个热点话题。你的应用越舒畅,用户体验就越好,转换率就越高。
也就是说,添加粗浅的CSS3动画或者不考虑后果的控制多个DOM元素会让我感到很惭愧。当在应用视觉效果时,浏览器中用到了两个术语:
重绘
重绘放生在元素的改变影响显示但不影响布局的时候。例如,opacity, background-color, visibility, 和outline。重绘是很昂贵的,因为浏览器必须检查DOM中所有的节点——在发生改变的元素下,一个或多个元素变的可见!
重排
重排会有更大的影响。这会涉及到所有元素位置和尺寸的重新计算,从而导致部分或者全部文档重渲染。改变单一的一个元素会影响到所有的子元素,祖先元素和兄弟元素。
两者都是浏览器拦截,在重绘或者重排发生期间,用户和你的应用程序都可以做其他的任务。在极端情况下,一个CSS效果可以导致javascript执行更慢。这就是你遇到诸如生涩的滚屏和界面无法响应的原因。
理解重排是怎么被触发的就很有用了:
1.添加,移除或者改变可视的DOM元素
第一点是显而易见的,用javascript改变DOM会导致重排。
2.添加,移除或者改变CSS样式
同样得,直接应用CSS样式或者改变类可能会改变布局。改变一个元素的宽度会影响同一个DOM分支下的所有元素和周围的元素。
3.CSS动画和过渡
动画的每一帧都会导致重排。
4.使用offsetWidthoffsetHeight
古怪地是,读取一个元素的``offsetWidthoffsetHeight```属性可以触发一个初始的重排,因此,这个数字能够被计算出来。
5.用户动作
最后,用户可以通过激发一个:hover效果来触发重排,在一个区域中输入文本,改变窗口的大小,改变字体的尺寸,切换样式表或者字体。
重排处理流程会有所不同。一些浏览器在确定的运算方面会比其他浏览器要好。。一些元素比某些元素渲染要更昂贵。幸运地是,这里有几个通用的技巧你可以运用,来提高性能。

1.使用最佳的布局技术

一个内联样式会影响布局因为HTML下载之后会触发一个额外的重排。表格是奢侈的,因为语法分析程序需要不止一个表格传递到计算单元面积。使用table-layout:fixed布局,由于列的宽度是基于标题行的内容的,所以它有助于当前的表格式数据。在你的主页面中使用flexbox布局,也会有性能问题,因为在HTML下载之后,伸缩元素的位置和尺寸会发生改变。

2.最小化CSS规则的数量

你所使用的规则越少,重排就越快。你也应该防止出现复杂的CSS选择器。如果你正在使用诸如bootstrap这类的框架,这会是特别有问题的。在提供的样式中极少的网站不止使用一个分数。像Unused CSS, uCSS, grunt-css和gulp-uncss这类的工具,可以显著的减少你的样式描述和文件大小。

3.最小化DOM深度

稍微有点复杂——减少你的DOM树的大小和每个分支的元素数量。你的文档越小,越浅,重排就会越快。如果你不支持旧版的浏览器,可能你要移除不需要的包裹元素。

4.少更新DOM树中的类

尽可能少的改变DOM树中元素的类。这可以限制让量的少的必要的区域重排。实质上,只对父节点应用类改变,例如,如果效果在子节点上的的包裹元素是最小的。

5.从流中移除复杂的动画

通过position:absolute 或者position:fixed移除文档流,确保动画是应用在一个单一的元素上。这允许修改元素的尺寸和位置,而不影响文档中的其他元素。

6.修改隐藏的元素

display:none隐藏的元素,当他们改变时,不会导致重绘或者重排。如果切实可行,在它可见之前来改变元素。

7.批量更新元素

通过在一个单一的操作中更新所有DOM,可以提高性能。下面这个简单的例子会导致三次reflow。

var myelement = document.getElementById('myelement');
myelement.width = '100px';
myelement.height = '200px';
myelement.style.margin = '10px';

我们可以减少到一次重排,也很容易。例如:

 var myelement = document.getElementById('myelement');
myelement.classList.add('newstyles');
.newstyles{
	width: 100px;
	height: 200px;
	margin: 10px;
}

你也可以减少你需要触摸的DOM的次数。让我们假定你想要创建这个清单:

item 1
item 2
item 3

一次添加一个元素会导致7次重排,一是当<ul>被添加时,三次因为每个<li>元素,三次因为文本。然而,在使用一个DOM片段和第一次在内存中建立节点时,一个单独的重排会被执行。例如:

var i, li,
   frag = document.createDocumentFragment(),
   ul = frag.appendChild(document.createElement(‘ul’));
for (i = 1; i <= 3; i++) {
   li = ul.appendChild(document.createElement(‘li’));
   li.textContent = ‘item’ + i;
}
document.body.appendChild(frag);

8.限制被影响的元素

防止大量的元素被影响这种情况。考虑到一个选项卡的内容控制,点击选项激活不同的的内容块儿。如果每个内容块周围的元素有不同的高度,周围的元素就会被影响。你可能会通过为容器设置一个固定的高度或者从文档流中移除控制,来提高性能。

9.认识到流畅危害到性能

一个元素每次移动一个像素可能会看起来流畅,但是在更低端的设备上却很难。通过每帧移动四个像素移动元素,需要四分之一的回流处理,可能只是稍微不那么流畅。

10.用浏览器工具分析重绘问题

所有主流的浏览器都提供开发者工具,强调了回流如何影响性能。在Blink/Webkit浏览器中,例如chrome,Safari,和opera,打开Timeline面板,并记录一个活动

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值