C03 渲染性能

2026-10-31 17:080 阅读约 9 分钟CSS

C03 渲染性能

摘要:浏览器渲染分三步:计算布局、绘制像素、合成图层。改动宽高会触发前三步,改动颜色只触发绘制,改动 transform 与 opacity 只触发合成。多数卡顿来自在滚动或动画中改动了布局属性。本文给出属性分类表、三个性能属性与一条定位流程。
关键词:重排,重绘,合成,contain,内容可见性

所属:frontend/css / C-高级 | 上一篇:C02-可维护CSS与命名分层 | 下一篇:C04-无障碍与视觉

1 引言

同一段动画,改动 margin 掉帧,改动 transform 流畅。差异不在代码量,而在浏览器需要重做哪几步。

本文给出三步模型与三个控制属性的用法。范围见表 1-1。

项 本文覆盖 本文不覆盖
渲染模型 布局、绘制、合成 GPU 与光栅化细节
属性 contain、content-visibility、will-change 滚动驱动动画
资源 图片尺寸、字体加载、关键样式 CDN 与缓存策略

2 预备知识

项 要求 核对方式
环境 本地服务器可用 浏览器能打开 localhost
文件 css-practice/perf.html 编码 UTF-8
浏览器 Chrome 130+,Performance 与 Rendering 面板 能录制并查看层级
前置 B05 动效写法已掌握

3 原理与实现

3.1 三步模型

属性改动影响哪一步,决定这次改动是否昂贵,如图 3-1 所示。

flowchart LR
    A["改 width / top / font-size"] --> B["布局 Layout"]
    B --> C["绘制 Paint"]
    C --> D["合成 Composite"]
    E["改 color / background"] --> C
    F["改 transform / opacity"] --> D

图 3-1 属性改动触发的渲染阶段

图上可见:布局阶段最贵,会牵连兄弟与祖先;合成阶段最便宜,动画应尽量落在这一层。

3.2 三个控制属性

/* 运行环境:Chrome 130+;css-practice/perf.css */
.list__item {
  contain: layout paint;          /* 隔离布局与绘制影响范围 */
}

.article__body {
  content-visibility: auto;        /* 视口外跳过渲染 */
  contain-intrinsic-size: auto 60rem;
}

.hero__title {
  will-change: transform;          /* 提前提示合成,谨慎使用 */
}

.hero__media { aspect-ratio: 16 / 9; }

@font-face {
  font-family: "Inter";
  src: url("./fonts/inter.woff2") format("woff2");
  font-display: swap;              /* 先显示回退字体,避免白屏 */
}

属性改动与成本见表 3-1。

改动属性 触发阶段 成本 建议
width、height 布局 + 绘制 + 合成 高 用 transform: scale 替代
top、left 布局 + 绘制 + 合成 高 用 translate
color、background 绘制 + 合成 中 控制重绘区域
box-shadow 绘制 + 合成 中 大范围阴影慎用动画
transform、opacity 合成 低 动画首选

三个性能属性见表 3-2。

属性 作用 风险
contain 限定布局与绘制的传播范围 误用会截断溢出内容
content-visibility 视口外内容跳过渲染 需配合 contain-intrinsic-size
will-change 提前提升合成层 滥用会占用显存,反而更慢
font-display: swap 字体加载期间使用回退字体 会出现字体切换闪烁

4 验证与讨论

  1. 打开 Performance 面板录制滚动,查找长任务与布局次数。
  2. 给列表项加 contain: layout paint,对比录制结果中的布局耗时。
  3. 给长文正文加 content-visibility: auto,查看首次渲染时间变化与滚动是否正常。
  4. 把动画属性从 top 改为 translate,对比帧率。
检查项 预期结果 说明
布局次数 滚动时布局次数明显减少 contain 生效
首屏渲染 长文页首屏更快 content-visibility
帧率 动画期间保持稳定 合成层动画
字体闪烁 先显示回退字体,后切换 font-display: swap

讨论与局限。 will-change 不应写在所有元素上,只在即将动画前一刻添加、结束移除为最佳。另 content-visibility 会让离屏内容的查找与锚点定位失效,长文页需保留 contain-intrinsic-size 以免滚动条跳动。

5 常见问题

现象 原因 处理
滚动卡顿 滚动中触发布局 改用 transform,加 contain
加 will-change 后更慢 合成层过多占用显存 只在动画期间添加
长文页首屏慢 一次渲染全部内容 content-visibility: auto
字体加载导致白屏 未设 font-display swap 或预加载字体
使用 content-visibility 后锚点失效 内容未渲染,定位不到 保留固有尺寸,或用于非锚点区域

6 结论

序号 结论 依据
1 属性改动分三步,布局最贵 图 3-1
2 动画只动 transform 与 opacity 表 3-1
3 contain 与 content-visibility 限定成本 表 3-2
4 性能问题先录制,再改代码 4 节步骤 1

参考文献

[1] MDN Web Docs · 渲染性能,https://developer.mozilla.org/zh-CN/docs/Web/Performance/How_browsers_work(访问于 2026-10-31)
[2] web.dev · 用 content-visibility 优化渲染,https://web.dev/articles/content-visibility(访问于 2026-10-31)

返回文章列表

评论 0

0/2000

还没有评论,快来抢沙发吧~