灵魂拷问第6篇:谈谈你对重绘和回流的理解

我们首先来回顾一下渲染流水线的流程:

接下来,我们将来以此为依据来介绍重绘和回流,以及让更新视图的另外一种方式——合成。

回流

首先介绍回流回流也叫重排

触发条件

简单来说,就是当我们对 DOM 结构的修改引发 DOM 几何尺寸变化的时候,会发生回流的过程。

具体一点,有以下的操作会触发回流:

  1. 一个 DOM 元素的几何属性变化,常见的几何属性有widthheightpaddingmarginlefttopborder 等等, 这个很好理解。
  2. 使 DOM 节点发生增减或者移动
  3. 读写 offset族、scroll族和client族属性的时候,浏览器为了获取这些值,需要进行回流操作。
  4. 调用 window.getComputedStyle 方法。

回流过程

依照上面的渲染流水线,触发回流的时候,如果 DOM 结构发生改变,则重新渲染 DOM 树,然后将后面的流程(包括主线程之外的任务)全部走一遍。

相当于将解析和合成的过程重新又走了一篇,开销是非常大的。

重绘

触发条件

当 DOM 的修改导致了样式的变化,并且没有影响几何属性的时候,会导致重绘(repaint)。

重绘过程

由于没有导致 DOM 几何属性的变化,因此元素的位置信息不需要更新,从而省去布局的过程。流程如下:

跳过了生成布局树建图层树的阶段,直接生成绘制列表,然后继续进行分块、生成位图等后面一系列操作。

可以看到,重绘不一定导致回流,但回流一定发生了重绘。

合成

还有一种情况,是直接合成。比如利用 CSS3 的transformopacityfilter这些属性就可以实现合成的效果,也就是大家常说的GPU加速

GPU加速的原因

在合成的情况下,会直接跳过布局和绘制流程,直接进入非主线程处理的部分,即直接交给合成线程处理。交给它处理有两大好处:

  1. 能够充分发挥GPU的优势。合成线程生成位图的过程中会调用线程池,并在其中使用GPU进行加速生成,而GPU 是擅长处理位图数据的。
  2. 没有占用主线程的资源,即使主线程卡住了,效果依然能够流畅地展示。

实践意义

知道上面的原理之后,对于开发过程有什么指导意义呢?

  1. 避免频繁使用 style,而是采用修改class的方式。
  2. 使用createDocumentFragment进行批量的 DOM 操作。
  3. 对于 resize、scroll 等进行防抖/节流处理。
  4. 添加 will-change: tranform ,让渲染引擎为其单独实现一个图层,当这些变换发生时,仅仅只是利用合成线程去处理这些变换,而不牵扯到主线程,大大提高渲染效率。当然这个变化不限于tranform, 任何可以实现合成效果的 CSS 属性都能用will-change来声明。这里有一个实际的例子,一行will-change: tranform拯救一个项目,点击直达

原文地址:https://www.cnblogs.com/guchengnan/p/12160676.html

时间: 2024-10-25 15:07:25

灵魂拷问第6篇:谈谈你对重绘和回流的理解的相关文章

灵魂拷问第9篇:HTTPS为什么让数据传输更安全?

谈到HTTPS, 就不得不谈到与之相对的HTTP.HTTP的特性是明文传输,因此在传输的每一个环节,数据都有可能被第三方窃取或者篡改,具体来说,HTTP 数据经过 TCP 层,然后经过WIFI路由器.运营商和目标服务器,这些环节中都可能被中间人拿到数据并进行篡改,也就是我们常说的中间人攻击. 为了防范这样一类攻击,我们不得已要引入新的加密方案,即 HTTPS. HTTPS并不是一个新的协议, 而是一个加强版的HTTP.其原理是在HTTP和TCP之间建立了一个中间层,当HTTP和TCP通信时并不是

灵魂拷问第1篇:能不能说一说浏览器缓存?

缓存是性能优化中非常重要的一环,浏览器的缓存机制对开发也是非常重要的知识点.接下来以三个部分来把浏览器的缓存机制说清楚: 强缓存 协商缓存 缓存位置 强缓存 浏览器中的缓存作用分为两种情况,一种是需要发送HTTP请求,一种是不需要发送. 首先是检查强缓存,这个阶段不需要发送HTTP请求. 如何来检查呢?通过相应的字段来进行,但是说起这个字段就有点门道了. 在HTTP/1.0和HTTP/1.1当中,这个字段是不一样的.在早期,也就是HTTP/1.0时期,使用的是Expires,而HTTP/1.1使

灵魂拷问第2篇:能不能说一说浏览器的本地存储?各自优劣如何?

浏览器的本地存储主要分为Cookie.WebStorage和IndexedDB, 其中WebStorage又可以分为localStorage和sessionStorage.接下来我们就来一一分析这些本地存储方案. Cookie Cookie 最开始被设计出来其实并不是来做本地存储的,而是为了弥补HTTP在状态管理上的不足. HTTP 协议是一个无状态协议,客户端向服务器发请求,服务器返回响应,故事就这样结束了,但是下次发请求如何让服务端知道客户端是谁呢? 这种背景下,就产生了 Cookie. C

灵魂拷问第7篇:能不能说一说XSS攻击?

什么是 XSS 攻击? XSS 全称是 Cross Site Scripting(即跨站脚本),为了和 CSS 区分,故叫它XSS.XSS 攻击是指浏览器中执行恶意脚本(无论是跨域还是同域),从而拿到用户的信息并进行操作. 这些操作一般可以完成下面这些事情: 窃取Cookie. 监听用户行为,比如输入账号密码后直接发送到黑客服务器. 修改 DOM 伪造登录表单. 在页面中生成浮窗广告. 通常情况,XSS 攻击的实现有三种方式——存储型.反射型和文档型.原理都比较简单,先来一一介绍一下. 存储型

灵魂拷问:如何检查Java数组中是否包含某个值 ?

摘自:https://www.cnblogs.com/qing-gee/p/12053156.html 在逛 programcreek 的时候,我发现了一些专注细节但价值连城的主题.比如说:如何检查Java数组中是否包含某个值 ?像这类灵魂拷问的主题,非常值得深入地研究一下. 另外,我想要告诉大家的是,作为程序员,我们千万不要轻视这些基础的知识点.因为基础的知识点是各种上层技术共同的基础,只有彻底地掌握了这些基础知识点,才能更好地理解程序的运行原理,做出更优化的产品. 我曾在某个技术论坛上分享过

灵魂拷问:Java如何获取数组和字符串的长度?length还是length()?

限时 1 秒钟给出答案,来来来,听我口令:"Java 如何获取数组和字符串的长度?length 还是 length()?" 在逛 programcreek 的时候,我发现了上面这个主题.说实话,我当时脑海中浮现出了这样一副惊心动魄的画面: 面试官老马坐在我的对面,地中海式的发型令我敬佩有加.尽管略显疲惫,但他仍然自信地向我抛出了上面这个问题.稍稍迟疑了一下,我回答说:"数组用 length,字符串用 length 跟上小括号".老马不愧是面试中的高手,一瞬间就从我的

面试灵魂拷问之JS,请问你头皮发麻没有?

JS数据类型之问-概念篇 1.JS原始数据类型有哪些?引用数据类型有哪些?在 JS 中,存在着 7 种原始值,分别是: boolean null undefined number string symbol bigint引用数据类型:对象Object(包含普通对象-Object,数组对象-Array,正则对象-RegExp,日期对象-Date,数学函数-Math)函数Function2.说出下面运行的结果,解释原因. function test(person) { person.age = 26

[灵魂拷问♂]系列

[灵魂拷问♂]系列 SP1043 GSS1 - Can you answer these queries I 题目:链接 大致题意:求区间最大子段和,不带修改. 题解: 对于每个线段树节点.维护以下几个值: l, r:左右端点 sum:区间和 val:区间最大子段和 lv:一定包括区间左端点的最大子段和 rv:一定包括区间右端点的最大子段和 lv转移:lv = max(左儿子的lv, 左儿子的sum + 右儿子的lv) rv转移:rv = max(右儿子的rv,右儿子的sum + 左儿子的rv)

工厂设计模式灵魂拷问-Java实现

show me the code and take to me,做的出来更要说的明白 GitHub项目JavaHouse同步收录 喜欢就点个赞呗! 你的支持是我分享的动力! 引入 我们经常听到工厂模式,比如说 Spring 用了工厂模式啦,面试也会被问到工厂模式等等,这见工厂模式是日常开发中比较重要的一种设计模式.其实工厂模式也是比较简单的一种设计模式,这年头似乎不了解工厂模式,你都不好意思说你学过 编程一样(手动狗头).那么,允许我灵魂拷问一下,你真的了解工厂模式吗. UML类图 不急,我们先