一文教会你何为重绘、回流?

这篇具有很好参考价值的文章主要介绍了一文教会你何为重绘、回流?。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

学习目标:

  • 了解前端Dom代码、css样式、js逻辑代码到浏览器展现过程
  • 了解什么是图层
  • 了解重绘与回流
  • 了解前端层面针对重绘、回流如何优化

css图层

浏览器在渲染一个页面时,会将页面分为很多个图层,图层有大有小,每个图层上有一个或多个节点。
也就是我们各种各样的Dom标签
一文教会你何为重绘、回流?
在渲染DOM的时候,浏览器所做的工作实际上是:
1. 获取DOM后分割为多个图层
2. 对每个图层的节点计算样式结果 (Recalculate style–样式重计算)
3. 为每个节点生成图形和位置 (Layout–布局,重排,回流)
4. 将每个节点绘制填充到图层位图中 (Paint–重绘)
5. 图层作为纹理上传至GPU
6. 组合多个图层到页面上生成最终屏幕图像 (Composite Layers–图层重组)

图层创建的条件

一文教会你何为重绘、回流?

Chrome浏览器满足以下任意情况就会创建图层:
1. 拥有具有3D变换的CSS属性
2. 使用加速视频解码的节点
3. 节点
4. CSS3动画的节点
5. 拥有CSS加速属性的元素(will-change)

重绘(Repaint)

重绘是一个元素外观的改变所触发的浏览器行为,例如改变outline、背景色等属性。浏览器会根据元素的新属性重新绘制,
使元素呈现新的外观。重绘不会带来重新布局,所以并不一定伴随回流。

需要注意的是:重绘是以图层为单位,如果图层中某个元素需要重绘,那么整个图层都需要重绘。
所以为了提高性能,我们应该让这些“变化的东西”拥有一个自己一个图层,
不过好在绝大多数的浏览器自己会为CSS3动画的节点自动创建图层。

回流

渲染对象在创建完成并添加到渲染树时,并不包含位置和大小信息。计算这些值的过程称为布局或回流

“重绘"不一定需要"回流”,比如改变某个网页元素的颜色,就只会触发"重绘",不会触发"回流",因为布局没有改变。
“回流"大多数情况下会导致"重绘”,比如改变一个网页元素的位置,就会同时触发"回流"和"重绘",因为布局改变了。

触发重绘的属性

    * color							* background								* outline-color
    * border-style					* background-image							* outline
    * border-radius					* background-position						* outline-style
    * visibility					* background-repeat							* outline-width
    * text-decoration				* background-size							* box-shadow

触发回流的属性

    * width						* top									* text-align
    * height					* bottom								* overflow-y
    * padding					* left									* font-weight
    * margin					* right									* overflow
    * display					* position								* font-family
    * border-width				* float									* line-height
    * border					* clear									* vertival-align
    * min-height														* white-space

常见的触发回流的操作

一文教会你何为重绘、回流?

Reflow(回流) 的成本比 Repaint(重绘) 的成本高很多很多。
一个结点的 Reflow 很有可能导致子结点,甚至父点以及同级结点的 Reflow。
在一些高性能的电脑上也许还没什么,但是如果 Reflow 发生在手机上,那么这个过程是非常痛苦和耗电的。

所以,下面这些动作有很大可能会是成本比较高的。
当你增加、删除、修改 DOM 结点时,会导致 Reflow , Repaint。
当你移动 DOM 的位置
当你修改 CSS 样式的时候。
当你 Resize 窗口的时候(移动端没有这个问题,因为移动端的缩放没有影响布局视口)
当你修改网页的默认字体时。
【获取某些属性时(width,height…)!!!!!】
注:display:none 会触发 reflow,而 visibility:hidden 只会触发 repaint,因为没有发生位置变化。

优化方案

我们已知:浏览器渲染页面时经历了如下“细致”的环节:
1. 计算需要被加载到节点上的样式结果(Recalculate style–样式重计算)
2. 为每个节点生成图形和位置(Layout–重排或回流)
3. 将每个节点填充到图层中(Paint–重绘)
4. 组合图层到页面上(Composite Layers–图层重组)
如果我们需要提升性能,需要做的就是减少浏览器在运行时所需要做的工作,即:尽量减少1234步。

【具体优化方案如下】:
1.元素位置移动变换时尽量使用CSS3的transform来代替对top left等的操作
变换(transform)和透明度(opacity)的改变仅仅影响图层的组合
2.【使用opacity来代替visibility】
(1).使用visibility不触发回流,但是依然重绘。
(2).直接使用opacity即触发重绘,又触发回流(GPU底层设计如此!)。
(3).opacity配合图层使用,即不触发重绘也不触发回流。
原因:
透明度的改变时,GPU在绘画时只是简单的降低之前已经画好的纹理的alpha值来达到效果,并不需要整体的重绘。
不过这个前提是这个被修改opacity本身必须是一个图层。
3.【不要使用table布局】
table-cell
4.将【多次改变样式属性的操作合并成一次】操作
不要一条一条地修改DOM的样式,预先定义好class,然后修改DOM的className
5.【将DOM离线后再修改】
由于display属性为none的元素不在渲染树中,对隐藏的元素操作不会引发其他元素的回流。
如果要对一个元素进行复杂的操作时,可以先隐藏它,操作完成后再显示。这样只在隐藏和显示时触发2次回流。
6.【利用文档碎片】(documentFragment)------vue使用了该种方式提升性能。
7.【不要把获取某些DOM节点的属性值放在一个循环里当成循环的变量】
当你请求向浏览器请求一些 style信息的时候,就会让浏览器flush队列,比如:
1. offsetTop, offsetLeft, offsetWidth, offsetHeight
2. scrollTop/Left/Width/Height
3. clientTop/Left/Width/Height
4. width,height
当你请求上面的一些属性的时候,浏览器为了给你最精确的值,需要刷新内部队列,
因为队列中可能会有影响到这些值的操作。即使你获取元素的布局和样式信息跟最近发生或改变的布局信息无关,
浏览器都会强行刷新渲染队列。
8.动画实现过程中,启用GPU硬件加速:transform: tranlateZ(0)
9.为动画元素新建图层,提高动画元素的z-index
10.编写动画时,尽量使用如下的API

requestAnimationFrame----请求动画帧

一文教会你何为重绘、回流?

1.window.requestAnimationFrame()
说明:该方法会告诉浏览器在下一次重绘回流之前调用你所指定的函数
1.参数:该方法使用一个回调函数作为参数,这个回调函数会在浏览器下一次重绘之前调用。
回调函数会被自动传入一个参数,DOMHighResTimeStamp,标识requestAnimationFrame()开始触发回调函数的当前时间

2.返回值:
一个 long 整数,请求 ID ,是回调列表中唯一的标识。是个非零值,没别的意义。你可以传这个值给 window.cancelAnimationFrame() 以取消回调函数。

备注:若你想在浏览器下次重绘之前继续更新下一帧动画,那么回调函数自身必须再次调用window.requestAnimationFrame()

2.window.cancelAnimationFrame(requestID)
取消一个先前通过调用window.requestAnimationFrame()方法添加到计划中的动画帧请求。
requestID是先前调用window.requestAnimationFrame()方法时返回的值,它是一个时间标识,用法与定时器的id类似。

写在最后

原 创 不 易 , 还 希 望 各 位 大 佬 支 持 一 下 \textcolor{blue}{原创不易,还希望各位大佬支持一下}

👍 点 赞 , 你 的 认 可 是 我 创 作 的 动 力 ! \textcolor{green}{点赞,你的认可是我创作的动力!}

⭐️ 收 藏 , 你 的 青 睐 是 我 努 力 的 方 向 ! \textcolor{green}{收藏,你的青睐是我努力的方向!}

✏️ 评 论 , 你 的 意 见 是 我 进 步 的 财 富 ! \textcolor{green}{评论,你的意见是我进步的财富!}

文章看完了,参与个投票吧,前端目前比较火的三大框架你更喜欢哪个?文章来源地址https://www.toymoban.com/news/detail-416973.html

到了这里,关于一文教会你何为重绘、回流?的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 一文教会你如何在SpringBoot项目里集成Hibernate

    最近的项目里集成了Hibernate,今天就来盘一盘什么是Hibernate,Hibernate有什么作用,以及如何在SpringBoot项目内集成Hibernate。 Hibernate是一个流行的ORM(对象关系映射)框架,它可以将Java对象映射到数据库表,从而方便地进行持久化操作。 在Spring Boot项目中,集成Hibernate可以帮助

    2024年02月06日
    浏览(44)
  • 一文教会你Linux 查看内存使用情况的几种方法

    在运行 Linux 系统的过程中为了让电脑或者服务器以最佳水平运行,常常需要监控内存统计信息。 那么今天我们就来看看有哪些方法可以访问所有相关信息并帮助管理员监控内存统计信息。 查看或者获取 Linux 中的内存使用情况既可以通过命令的方式,也可以通过桌面端的GU

    2024年02月10日
    浏览(38)
  • 一文读懂Elephant Swap,为何为ePLATO带来如此高的溢价?

    自今年4月以来,在经历了UST脱锚,所引发的头部投资机构、独角兽CeFi平台的相继“破产”,加密行业迎来了前所未有的发展危机,一方面在于市场信心不足甚至恐慌,导致的资金加速出逃,另一方面市场整体增速缓慢导致各个板块收益疲软,导致投资者们难以获得可观的收

    2023年04月15日
    浏览(29)
  • 用通俗易懂的方式讲解:一文教会你学会 AI 绘画利器 Stable Diffusion

    随着 stable-diffusion 的开源,让更多人有机会直接参与到 AI 绘画的创作中,相关的教程也如雨后春笋般的出现。可是目前我看到的教程同质性较高,通常只能称作为\\\"使用流程讲解\\\",但是通常没有对其原理和逻辑进行深入说明。 所以本文的目的,是用尽可能少的废话,给大家补

    2024年01月18日
    浏览(36)
  • 【链表】还不会用C++实现链表?一文教会你各种链表的实现

    本文将用C++语言来实现数据结构中的无头单链表,带头循环链表,以及带头循环双向链表等链表结构(带头单链表与后两种链表的结构相似,实现起来比后两种更简单,读者阅读完本文即可自行实现) 无头单链表在头插时需要改变头指针的位置,具体代码实现如下: 带头意

    2024年02月08日
    浏览(31)
  • 一文教会你用Apache SeaTunnel Zeta离线把数据从MySQL同步到StarRocks

    在上一篇文章中,我们介绍了如何下载安装部署SeaTunnel Zeta服务(3分钟部署SeaTunnel Zeta单节点Standalone模式环境),接下来我们介绍一下SeaTunnel支持的第一个同步场景:离线批量同步。顾名思意,离线批量同步需要用户定义好SeaTunnel JobConfig,选择批处理模式,作业启动后开始同

    2024年02月06日
    浏览(68)
  • K8S二进制部署详解,一文教会你部署高可用K8S集群

    Pod网段: 10.0.0.0/16 Service网段: 10.255.0.0/16 集群角色 ip 主机名 安装组件 控制节点 10.10.0.10 master01 apiserver、controller-manager、scheduler、etcd、docker、keepalived、nginx 控制节点 10.10.0.11 master02 apiserver、controller-manager、scheduler、etcd、docker、keepalived、nginx 控制节点 10.10.0.12 master03 apiser

    2024年04月28日
    浏览(32)
  • 一文教会你使用AI绘画利器Stable Diffusion!这可能是CSDN最全的AI绘画使用教程,建议收藏!

    大家好,我是程序员晓晓 随着 stable-diffusion 的开源,让更多人有机会直接参与到 AI 绘画的创作中,相关的教程也如雨后春笋般的出现。可是目前我看到的教程同质性较高,通常只能称作为\\\"使用流程讲解\\\",但是通常没有对其原理和逻辑进行深入说明。 所以本文的目的,是用

    2024年01月25日
    浏览(36)
  • 一文教会你 如何在Github中创建仓库?如何将多个项目放到一个仓库中管理?如何将本地项目上传到GitHub中?

    一个混迹于Github、Stack Overflow、开源中国、CSDN、博客园、稀土掘金、51CTO等 的野生程序员。 目标:分享更多的知识,充实自己,帮助他人 GitHub公共仓库:https://github.com/zhengyuzh 以github为主: 1、分享前端+后端基础知识 2、前后端框架知识+框架使用分析 3、热门前端+后端面试题

    2024年01月17日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包