影响回流、重绘的 CSS 属性有哪些?

简介: 影响回流、重绘的 CSS 属性有哪些?

前言


目前,比较常见的浏览器内核(渲染引擎)有:WebKitBlinkGeckoTridentEdgeHTML,更多请看


  • WebKit 课代表是 Safari 浏览器
  • Blink 课代表是 Chrome 浏览器(Blink 起源自 WebKit 的一个分支)
  • Gecko 课代表是 Firefox 浏览器
  • Trident 课代表是 IE 浏览器。2015 年微软推出的 Edge 浏览器其内核是 EdgeHTML。从良之后于 2020 年推出基于 Chromium 的 Edge 浏览器,使用 Blink 引擎。

以下是两个主流浏览器内核 WebKit、Gecko 合成 DOM 的过程:

6.webp.jpg

WebKit

7.webp.jpg

Gecko

两者整体流程基本相似,在术语方面也有所不同,比如 WebKit 中的 Layout 过程,Gecko 称为 Reflow


提高网页性能的其中一个方式就是,减少回流(reflow)、重绘(repaint),分别对应 LayoutPainting 过程。


比如,React Hooks 中处理副作用时,某些场景下应选择 useLayoutEffect,而不是 useEffect 的原因正是为了减少回流重绘的过程。

「回流」也有称作「重排」的。


正文


什么是卡顿?


在很长一段时间里,显示器的刷新率多数为 60Hz,即使到现在仍然是占多数。

刷新率(RefreshRate),表示单位时间内能够绘制新图像的次数。举个例子,60Hz 的刷新率,表示显示器要在一秒内刷新 60 次图像,换句话说,一次图像的更新要在 16.67ms 内完成。这样才不会造成卡顿。如果超出这个时间,在视角上就会产生卡顿感。


60Hz 的刷新率是人类不会感觉到屏幕图像闪烁的数值,由科学家验证得出。

附一个来自网上的图:


11.webp.jpg

还是用 React 举例吧。我们知道 React 16 起采用了全新的 Fiber 架构,就是为了解决大型应用卡顿的问题。

我们知道,浏览器是多进程的,JavaScript 是单线程的。浏览器会为每个标签(Tab)分配一个进程,每个进程由 GUI 渲染线程、JS 线程、定时器线程、网络线程、事件线程多个线程组成。最重要的一点是:GUI 渲染线程与 JS 线程是互斥的。换句话说,某个时刻它只能执行其中一个线程,等待该线程执行完毕之后,才将执行权交由另一个线程。

那么为什么 React 15 在处理大型应用的时候会卡顿呢?

首先 React 15 架构,由协调器(Reconciler)和渲染器(Render)组成。而 React 16 在原来的基础上新增了调度器(Scheduler),用于调度任务的优先级。

在 React 15 的 Reconciler 中,组件的挂载(Mounting)、更新(Updating)会对应调用 mountComponentupdateComponent 方法,它们内部会执行递归操作,以更新子组件。但是递归执行的缺点是「无法中断」。假设 JS 线程执行递归耗时超过了 16.67ms,由于互斥期间 GUI 线程并不能执行任何的操作,等递归完并生成新的虚拟 DOM 之后,触发 DOM 等更新,此时由 GUI 线程进行处理,可能包括回流、重绘的过程,然后才完成一次页面的更新。由于无法满足刷新率的要求,就会产生卡顿感。

因此,解决卡顿的思路就是:在每一帧的时间内,预留一些时间给 JS 线程,当预留的时间不够用时,React 中断当前任务,将线程控制权交换给浏览器,使其有时间渲染页面,等下一帧到来的时候,继续被中断的工作。

在 React 16 新增的 Scheduler 可以使得浏览器有剩余时间的时候通知 React,而且提供了多种调度优先级,使得更高优先级的任务优先进入 Reconciler 阶段。 而 Reconciler 则是利用了 Fiber 这种架构实现了「可中断的异步更新」(请注意,这里的异步并不是由 setTimeout 实现的,由于精度问题,setTimeout 实际上最低延迟时间是 4ms,在这寸土寸金的一帧时间才 16.67ms,显然是不合理的)。

因此,React 就是采用了这种思路来解决大型应用卡顿问题的。

题外话扯完了,回到本文的主题...


影响页面渲染性能的有什么?


再附上一张源自网上的图:


8.webp.jpg


这几个关键点:

  • JavaScript - 使用 JavaScript 脚本来触发 DOM 的更新。
  • Style - 匹配各种选择器,并计算出哪些元素应用哪些 CSS 样式的过程。
  • Layout - 前面知道一个元素应用哪些规则之后,浏览器开始计算它要占用的空间大小以及在屏幕的位置。一个元素在空间上的变化,会同时影响其他元素的重排。
  • Paint - 绘制是填充的像素的过程,比如文本、颜色、图像、边框和阴影等。
  • Composite - 合成过程处理元素绘制到哪一层,可能是在某个元素的上层或下层。与层叠上下文有关。

  1. 如果修改了某个元素的 Layout 属性,那么浏览器会检查其他所有元素,然后“自动重排”,任何受影响的部分都需要重新绘制,然后才进行合成。
  2. 如果仅修改了「paint only」属性,比如背景图片,文字颜色、背景等,它不会影响页面布局,所以会跳过 Layout 阶段,然后执行重绘。
  3. 如果修改了一个既不影响 Layout,也无需 Paint 的属性,那么浏览器只执行 Composite 合成过程。这个开销是最小的,可以看下这篇文章


CSS Triggers


哪些 CSS 属性影响 Layout,哪些影响 Paint 呢?

可以看这个网站 CSS Triggers

9.webp.jpg


其中 Change from default 表示从未设置(即 CSS 默认值)到设置为其他值,Subsequent updates 表示属性修改。


References


目录
相关文章
|
2月前
|
前端开发
css的渐变属性linear-gradient
css的渐变属性linear-gradient
|
2月前
|
前端开发
CSS属性:盒子模型
CSS属性:盒子模型
33 0
|
2月前
|
前端开发
CSS属性
CSS属性
30 0
|
22天前
|
Web App开发 前端开发 iOS开发
css所有缩写属性,CSS属性简写整理
css所有缩写属性,CSS属性简写整理
19 1
|
2月前
|
前端开发
前端基础(五)_CSS文本文字属性、背景颜色属性
本文详细介绍了CSS中关于文本和背景颜色的样式属性。包括字体大小、字体族、字体加粗、字体样式、文本行高、`font`属性、文本颜色、文本对齐方式、文本装饰线、首行缩进等文本属性,以及背景颜色、背景图片、背景重复、背景位置等背景属性。文章通过示例代码展示了这些属性的具体应用和效果。
37 3
前端基础(五)_CSS文本文字属性、背景颜色属性
|
1月前
|
前端开发
CSS 中哪些属性可以继承
在 CSS 中,属性分为可继承与不可继承。可继承属性会在子元素中沿用父元素的样式设定。常见可继承属性包括:文本属性(如 `font-family`, `color`),列表属性(如 `list-style`),表格布局属性(如 `border-collapse`),以及其他如 `visibility` 和 `direction` 等属性。正确理解这些属性有助于更高效地进行样式设计。
|
22天前
|
前端开发
css简写属性
css简写属性
26 0
|
1月前
|
前端开发 JavaScript
如何在CSS中添加自定义属性
如何在CSS中添加自定义属性
16 0
|
1月前
|
前端开发
运用CSS伪类与属性,巧妙实现背景图片旋转效果
运用CSS伪类与属性,巧妙实现背景图片旋转效果
33 0
|
1月前
|
前端开发
哪些 CSS 属性可以继承?
哪些 CSS 属性可以继承?
45 0

热门文章

最新文章

下一篇
无影云桌面