前端百题斩【031】——从渲染流程认识重绘和回流

简介: 前端百题斩【031】——从渲染流程认识重绘和回流

在“浏览器的渲染流程”一节中已经详细阐述了渲染过程的几个关键步骤,其简要流程图如下所示:


640.png


今天的主角“重绘和回流”就会导致浏览器触发更新,重新进行渲染绘制,但是两者稍有不同,重绘不会存在布局阶段,而回流会进行重新布局,所以回流代价更高、损耗更大。


31.1 重绘


重绘是指页面中某些元素发生了不影响布局的变化时(如颜色改变),浏览器重新绘制的过程。此时由于只需要UI层面的重新像素绘制,因此损耗较少。仅仅引发重绘的操作如下所示(注意:回流必定触发重绘,但是重绘不一定触发回流):


  1. 改变背景色;
  2. 改变文字颜色;
  3. 改变边框颜色;
  4. 通过visibility:hidden隐藏元素;
  5. ……


31.2 回流



回流是指页面中某些元素发生变化而影响了布局时(如尺寸、位置改变),浏览器需要重新布局并绘制的过程。引发回流的操作如下所示:


  1. 页面初次渲染;
  2. 浏览器窗口大小改变;
  3. 元素尺寸、位置、内容发生改变;
  4. 元素字体大小变化;
  5. 添加或者删除可见的 dom 元素;
  6. 激活 CSS 伪类(例如::hover);
  7. 查询某些属性或调用某些方法:


  • clientWidth、clientHeight、clientTop、clientLeft
  • offsetWidth、offsetHeight、offsetTop、offsetLeft
  • scrollWidth、scrollHeight、scrollTop、scrollLeft
  • getComputedStyle() :Window.getComputedStyle()方法返回一个对象,该对象在应用活动样式表并解析这些值可能包含的任何基本计算后报告元素的所有CSS属性的值。
  • getBoundingClientRect()
  • scrollTo():scrollTo() 方法可把内容滚动到指定的坐标。


31.3 减少回流和重绘



31.3.1 浏览器自身优化策略


  1. 由于每次重排都会造成额外的计算消耗,因此大多数浏览器都会通过队列化修改并批量执行来优化重排过程。浏览器会将修改操作放入队列里,直到过了一段时间或者操作达到了一个阈值,才清空队列。当你获取布局信息的操作的时候,会强制队列刷新,比如访问以下属性或者使用以下方法:


  • offsetTop、offsetLeft、offsetWidth、offsetHeight
  • scrollTop、scrollLeft、scrollWidth、scrollHeight
  • clientTop、clientLeft、clientWidth、clientHeight
  • getComputedStyle()
  • getBoundingClientRect


以上属性和方法都需要返回最新的布局信息,因此浏览器不得不清空队列,触发回流重绘来返回正确的值。因此,在修改样式的时候,最好避免使用上面列出的属性,它们都会刷新渲染队列。如果要使用它们,最好将值缓存起来。


  1. 另一优化就是浏览器认为position为absolute或fixed的元素更改只会影响其本身和子元素,而static的元素变化则会影响之后的所有元素。原因在于absolute和fixed认为元素从文档流中清除了,怎么操作是内部的事。例如:对于复杂动画效果,使用绝对定位让其脱离文档流


31.3.2 多次操作变为一次操作


  1. 不要一条一条的修改DOM的样式,尽量使用class进行样式修改。
  2. 把DOM离线修改(批量修改DOM)

(1)使用documentFragment对象在内存里操作DOM

(2)先把DOM给display:none,修改完毕再显示出来

(3)clone一个DOM节点到内存里,然后想怎么改就怎么改,改完后,和在线的那个的交换一下。


31.3.3 其它


  1. 使用css3硬件加速,可以让transform、opacity、filters(滤镜)这些动画不会引起回流重绘(注意:对于动画的其它属性,比如background-color这些,还是会引起回流重绘的,不过它还是可以提升这些动画的性能)
  2. 不要把DOM结点的属性值放在一个循环里当成循环里的变量。不然这会导致大量地读写这个结点的属性。
  3. 千万不要使用table布局。因为可能很小的一个小改动会造成整个table的重新布局。
相关文章
|
12天前
|
缓存 前端开发 中间件
[go 面试] 前端请求到后端API的中间件流程解析
[go 面试] 前端请求到后端API的中间件流程解析
|
9天前
|
缓存 前端开发 JavaScript
优化前端性能:从渲染到加载的全方位策略
前端性能优化是提升用户体验的关键因素。本文探讨了从浏览器渲染到资源加载的各个方面,介绍了使用现代工具和技术的策略,包括减少关键渲染路径、优化资源加载和利用缓存。通过实施这些策略,可以显著提高页面响应速度,减少加载时间,提供更流畅的用户体验。
|
1月前
|
前端开发 NoSQL 数据库
部署常用的流程,可以用后端,连接宝塔,将IP地址修改好,本地只要连接好了,在本地上前后端跑起来,前端能够跑起来,改好了config.js资料,后端修改好数据库和连接redis,本地上跑成功了,再改
部署常用的流程,可以用后端,连接宝塔,将IP地址修改好,本地只要连接好了,在本地上前后端跑起来,前端能够跑起来,改好了config.js资料,后端修改好数据库和连接redis,本地上跑成功了,再改
|
1月前
|
前端开发 JavaScript
Vue前端渲染blob二进制对象图片的方法
Vue前端渲染blob二进制对象图片的方法
40 0
|
1月前
|
JavaScript 前端开发
【vue】 接口返回的preview是张图片,前端如何渲染
【vue】 接口返回的preview是张图片,前端如何渲染
70 0
|
2月前
|
缓存 前端开发 JavaScript
【前端性能优化】深入解析重绘和回流,构建高性能Web界面
【前端性能优化】深入解析重绘和回流,构建高性能Web界面
35 1
|
2月前
|
缓存 前端开发 JavaScript
Webpack作为模块打包器,为前端项目提供了高度灵活和可配置的构建流程
【6月更文挑战第12天】本文探讨了优化TypeScript与Webpack构建性能的策略。理解Webpack的解析、构建和生成阶段是关键。优化包括:调整tsconfig.json(如关闭不必要的类型检查)和webpack.config.js选项,启用Webpack缓存,实现增量构建,代码拆分和懒加载。这些方法能提升构建速度,提高开发效率。
46 3
|
2月前
|
缓存 前端开发 JavaScript
前端性能优化:从加载到渲染的全方位探索
【6月更文挑战第11天】本文探讨了前端性能优化,重点关注加载速度和渲染效率。压缩与优化资源文件、利用CDN、异步加载和懒加载可提升加载速度。减少DOM操作、合理利用CSS和JavaScript、优化JavaScript执行效率以及利用浏览器缓存能提高渲染效率。通过综合运用这些策略,可提升用户体验。
|
1月前
|
前端开发
若依部署,部署常见流程之先部署网页的后端系统,让自己的前端能够看到内容,先部署后端,让前端在本地跑起来-----吃饱了撑死了大佬建议,正确的部署流程
若依部署,部署常见流程之先部署网页的后端系统,让自己的前端能够看到内容,先部署后端,让前端在本地跑起来-----吃饱了撑死了大佬建议,正确的部署流程
|
7天前
|
存储 前端开发 JavaScript
前端语言串讲 | 青训营笔记
前端语言串讲 | 青训营笔记
10 0