当前位置: 首页 > 科技观察

前端100题从渲染过程切入了解重绘和回流

时间:2023-03-16 15:08:08 科技观察

在“浏览器渲染过程”部分,已经详细讲解了渲染过程中的几个关键步骤。简要流程图如下:今天的主角“重绘回流”会导致浏览器触发一次更新,重新渲染绘制,但两者略有不同。重绘不会有布局阶段,而回流会重新布局,所以回流更昂贵和有损。.31.1重绘重绘是指页面上的某些元素发生不影响布局的变化(如颜色变化)时,浏览器进行重绘的过程。此时,由于只需要在UI层面重新进行像素渲染,所以损失较小。只引起重绘的操作如下(注:回流一定会触发重绘,但重绘不一定会触发回流):改变背景颜色;改变文字颜色;更改边框颜色;通过可见性隐藏元素:hidden;...31.2ReflowReflow是指当页面中的某些元素发生变化并影响布局(如大小和位置变化)时,浏览器需要重新布局和绘制的过程。触发回流的操作如下:页面的初始渲染;浏览器窗口大小改变;元素大小、位置、内容变化;元素字体大小更改;添加或删除可见的dom元素;激活CSS伪类(例如:悬停);查询某些属性或调用某些方法:clientWidth、clientHeight、clientTop、clientLeft这些值在报告任何基础计算元素后可能包含的任何CSS属性的值。getBoundingClientRect()scrollTo():scrollTo()方法可以将内容滚动到指定坐标。31.3减少重排和重绘31.3.1浏览器自身的优化策略由于每次重排都会造成额外的计算消耗,因此大多数浏览器会通过排队修改并批量执行来优化重排过程。浏览器会将修改操作放入队列中,等待一段时间或操作达到阈值后才会清空队列。当获取到布局信息的操作时,队列会被强制刷新,比如访问下面的属性或者使用下面的方法:上面的getComputedStyle()getBoundingClientRect属性和方法都需要返回最新的布局信息,因此浏览器不得不清空队列并触发回流以返回正确的值。因此,在修改样式时,最好避免使用上面列出的属性,它们都会刷新渲染队列。如果您要使用它们,最好缓存这些值。另一个优化是浏览器认为一个position是absolute或者fixed的元素的改变只会影响它自己和它的子元素,而static元素的改变会影响到所有后续的元素。原因是absolute和fixed认为元素从文档流中清除,如何操作是内部的事情。例如:对于复杂的动画效果,使用绝对定位使其脱离文档流。31.3.2多操作成为一个操作不要一一修改DOM样式,尽量使用class进行样式修改。离线修改DOM(批量修改DOM)(1)使用documentFragment对象操作内存中的DOM(2)先给DOM显示:none,修改后再显示(3)clone一个DOM节点到内存中,然后思考关于怎么办想怎么改就怎么改,改完之后再和网上的交换。31.3.3Others使用css3硬件加速可以让transform、opacity、filters(滤镜)等动画不会引起回流重绘(注意:对于动画的其他属性,比如background-color,仍然会引起回流重绘,但是它仍然可以提高这些动画的性能)不要将DOM节点的属性值作为循环中的变量放在循环中。否则会导致对该节点属性的大量读写。切勿使用表格布局。因为一个小小的改动就可能导致整个表格重新布局。本文转载自微信公众号“牵着风筝”,可通过以下二维码关注。转载本文请联系风筝持有人公众号。