03渲染优化-02回流与重绘

博客围绕页面布局与绘制展开,指出布局和绘制在关键渲染路径中消耗较高,提升性能需避免。介绍了回流的概念、影响操作及避免回流抖动的方法,如使用最佳布局、读写分离等,还讲解了重绘,最后给出动画抖动的示例及解决办法。

1.布局(layout)与绘制(paint)

在关键渲染路径中,布局和绘制是消耗相对来说比较高的操作。
要提升页面性能,尽量避免布局和绘制是很好的方法之一。

渲染树只包含网页需要的节点

  • 布局:计算每个节点精确的位置大小
  • 绘制:像素化每个节点的过程。

1.1回流

当render tree中的一部分(或全部)因为元素的规模尺寸,布局,隐藏等改变而需要重新构建。这就称为回流(reflow)。
第一次Layout:布局;
从第二次开始Layout:回流;

1.1.1 影响回流的操作

  • 添加/删除元素
  • 操作styles
  • display:none
  • offsetLeft,scrollTop,clientWidth
  • 移动元素位置
  • 修改浏览器大小,字体大小

1.1.2 避免回流抖动(布局抖动)

避免回流

通用技巧

  • 使用最佳布局方案

不要使用内联样式和table布局!
内联样式会在下载HTML时影响布局,并触发额外的reflow。
table布局开销很大,因为解析器需要多次传递去计算单元格维度,使用table时应用fixed定位有一定的优化效果,因为列的宽度是基于标题行的内容。
主页面布局应用flexbox也会有性能影响,因为在HTML下载的时候,flex items的位置和尺寸可能会变化。

  • 最小化CSS规则的数量

css规则越少,重排越快,要尽量避免复杂的css选择器。
如果您使用的是Bootstrap这样的框架,那么这一点尤其成问题——很少有站点使用了框架提供的所有样式。像Unused CSS、uCSS、grunt-uncss和gulp-uncss这样的工具可以显著减少样式定义和文件大小

  • 最小化DOM层级

稍微复杂一点——减小DOM树大小和每个分支的元素数量。文档越小越浅,回流越快。如果不需要支持古老的浏览器,可以删除不必要的包裹元素。

  • 更改class的DOM层级要低

改变class的DOM层级尽可能的低(比如:没有多个深度嵌套的元素),这能减小重排的范围,只重排必要的元素,本质上,只有在对嵌套子节点的影响很小的情况下,才将类更改应用于父节点,比如包装器。

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

通过使用position: absolute; 或者 position: fixed;来使有动效的元素脱离文档流,这可以在不影响文档流中的其它元素的情况下更新尺寸和位置。

  • 更新隐藏的元素

通过display: none;来隐藏的元素在改变时不会触发重绘和重排,可以的话,在元素可见之前进行更改

  • 批量更新元素

所有的DOM操作在同一次动作中进行能提高性能。
下面这个简单的例子会引起3次重排:

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

我们可以把上面的操作减少到1次重排,这也更便于维护:

var myelement = document.getElementById('myelement');
myelement.classList.add('newstyles');
.newstyles {
 width: 100px;
 height: 200px;
 margin: 10px;
}
  • 限制受影响的元素

避免大量元素受影响的情况。
比如:一个选项卡内容控件,单击一个选项卡将激活不同的内容块。如果每个内容块的高度不同,则会影响周围的元素。
可以为容器设置固定高度或从文档流中删除控件来提高性能。

  • 意识到平滑影响性能

每帧移动1px看起来平滑,但是低端机会卡顿,每帧移动4px,需要1/4的重排,且可能只会稍微不那么平滑。

读写分离

读: 读取当前的布局
写: 批量的写入(更新)新的布局。

如:当前页面常用的前端框架vue.js和react,都使用了vDOM,把要更新/新增的元素全部都设置为VDOM;VDOM全部完成后,一次性的更新到DOM中,这样就可以避免大量重复性的回流

1.2重绘

在回流的时候,浏览器会使渲染树中受到影响的部分失效,并重新构造这部分渲染树,完成回流后,浏览器会重新绘制受影响的部分到屏幕中,该过程成为重绘。


动画抖动Demo

抖动

在这里插入图片描述

  • 如上演示,鼠标从div上滑过时,会出现抖动现象,并且动画不能正常显示为60%的高度。
  • 原因是:鼠标滑过时动画生效,height变为0%,而此时鼠标就处于div的外部状态,hover不能生效,因此完整动画不能正常展示。
  • 解决方法:使div出现抖动的效果height一直在0%~20%之间,解决方法把动画中的from的height设置为20%即可。

抖动解决在这里插入图片描述

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值