大数跨境

提高Web页面性能的技巧

提高Web页面性能的技巧 慧测
2016-03-21
1
导读:现在动辄几兆大小的页面加载量,让性能优化成了不可避免的热门话题。WEB 应用越流畅,用户体验就会越好,继而带


现在动辄几兆大小的页面加载量,让性能优化成了不可避免的热门话题。WEB应用越流畅,用户体验就会越好,继而带来更多的访问量。这也就是说,我们应该反省一下那些过度美化的CSS3动画和多重操作的DOM元素是否都考虑到了在性能方面的影响。在说性能优化之前,我们有必要理清浏览器视觉绘制方面的两个术语:

Repaint(重绘):如果某些操作影响了DOM元素的可见性,但又没有影响布局,那么就会发生浏览器的重绘,比如opacity,background-color,visibility和outline属性。由于浏览器必须检查DOM中所有节点的可见性——某些图层或许会置于重绘元素的图层下面,所以重绘是一个非常繁重的逻辑。

Reflow(回流):回流是一个更具破坏性的操作,它会让浏览器重新计算所有元素的坐标位置和尺寸大小。往往由于一个元素的变化,继而引起其子元素、父元素以及相邻元素的变化。

不管用户或者应用本身是否正在执行某些逻辑,这两种操作都会阻塞浏览器进程。极端情况下,一个CSS效果会降低JavaScript的执行速度。下面是触发回流事件的几种情境:

添加、删除和修改可见的DOM元素

添加、删除和修改部分CSS样式,比如修改元素的宽度,会影响其相邻元素的布局位置

CSS3动画和过渡效果

使用offsetWidth和offsetHeight。这种情境很诡异,读取一个元素的offsetWidth和offsetHeight属性会触发回流

用户行为,比如鼠标悬停、输入文本、调整窗口大小、修改字体样式等等

浏览器的底层实现各有不同,所以渲染页面的开销也各有轻重。好在我们有一些通常规则可以进行性能优化。

使用最佳实践所建议的布局技巧

虽然已经是2015了,但我还是要说不要使用行内联样式和table布局。

HTML文档下载完成后,行内样式会触发一次额外的回流事件。解析器在解析table布局时需要计算大量的单元格的尺寸,所以是件很重的操作。由于单元格往往是根据表头宽度确定的,所以使用table-layout:fixed可以缓解部分性能消耗。

使用Flexbox布局也存在性能损失,因为在页面加载完成后,flex item可能会发生位置和尺寸的变化。

精简CSS样式

样式越少,回流越快,此外,尽量不要使用过于复杂的选择器。这一问题尤其突出在使用类似Bootstrap框架的网站上。使用Unused CSS,uCSS,grunt-uncss和gulp-uncss等工具可以有效剔除无用样式。

精简DOM层级

精简DOM层级,指的是减少DOM树的级数已经每一分支上DOM元素的数量,结果就是层级越少、数量越少,回流越快。此外,如果无需考虑旧版本浏览器,应该尽量剔除无意义的包裹类标签和层级。

细粒度操作DOM树

操作DOM树时的粒度要尽可能细化,这有助于减弱局部DOM变化给整体带来的影响。

从文档流中移除复杂的动画效果

应该确保使用动画的元素脱离了文档流,使用position:absolute和position:fixed属性脱离文档流的元素会被浏览器创建一个新层来存放,这些图层上的修改不会影响其他图层上的元素。

巧用隐藏方式

使用Display:none;隐藏的元素不会触发页面的重绘和回流事件,所以可以在这些元素隐藏期间配置样式,配置完成后再转换为可见状态。

批量更新元素

单词更新所有DOM元素的性能要优于多次更新。下面这段代码触发了三次页面回流:

1

2

3

4

varmyelement=document.getElementById('myelement');

myelement.width='100px';

myelement.height='200px';

myelement.style.margin='10px';

通过以下代码可以精简为一次页面回流事件,并且提高了代码的可维护性:

1

2

3

4

5

6

7

8

varmyelement=document.getElementById('myelement');

myelement.classList.add('newstyles');

.newstyles{

width:100px;

height:200px;

margin:10px;

}

同理,我们还可以减少操作DOM的频率。假设我们要创建一个如下所示的无序列表:

如果分次添加每一个item将会触发多次页面回流,简单而高效的方式是使用DOMfargment在内存中创建完整的DOM节点,然后一次性添加到DOM中:

1

2

3

4

5

6

7

8

9

10

11

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);

约束元素变化的影响

这里的约束是指,尽量避免某个元素的变化引起大范围的变化。假设我们有一个tab选项卡的组件,选项卡内部的内容长短不一,这就导致了每个选项卡的高度不唯一。这一设计带来的问题就是每次切换选项卡时,周围的元素都要重新布局。我们可以通过一个固定高度来避免这一情况。

权衡流畅度和性能

一次移动一像素的位置看起来虽然很流畅,但对于某些低性能终端会是很大的压力。一次移动四像素降低帧速虽然看起来稍有些迟钝,但性能压力降低了。这就是需要我们权衡的地方:流畅度和性能。

使用开发者工具分析页面重绘

目前主流浏览器都在开发者工具中提供了监控页面重绘的功能。在Blink/Webkit内核的浏览器中,使用Timeline面板可以记录一个页面活动详情:

下面是火狐开发者工具中的 TimeLine:

在IE中这个功能被放置在了UI Responsiveness面板中:

所有的浏览器都使用绿色来显示页面重绘和页面回流事件。上面的测试只是几个简单的示例,其中没有调用繁重的动画效果,所以布局渲染在总时间中占据了较大比重。减少页面回流和页面重绘,自然提高页面性能。


公益传播测试知识、技能与正能量!感谢作者!分享测试生活,思考测试人生!
文章图片来自网络,如有侵权请见谅,请联系我们妥善处理。
twftesting@163.com


欢迎加入我们:

官网:www.huicewang.com
中国软件测试群: 172923163  

测试编程技术交流群: 231767115  

性能测试技术交流群: 385202672

咨询QQ:2657535456

公众号:慧测


【声明】内容源于网络
0
0
慧测
专注人工智能前沿技术落地企业实战应用
内容 404
粉丝 0
慧测 专注人工智能前沿技术落地企业实战应用
总阅读104
粉丝0
内容404