Files
TrueGrowth/docs/MEDIA_LIBRARY_RENDER_PERFORMANCE_LESSONS.md

87 lines
3.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 素材库渲染性能经验
更新日期2026-04-27
## 背景
部分用户打开素材库后,在素材卡片上移动鼠标会感到整个页面抖动;素材库弹窗标题偶尔消失。
这类问题不要只按“素材太多”处理。素材库本身已使用虚拟滚动,更常见的瓶颈来自高频 hover 下的弹层、阴影、透明模糊和窗口实例冲突。
## 根因
### 1. 高频 hover 不能批量创建弹层
素材卡片里每个名称、徽章、按钮都包 `Tooltip` 时,鼠标快速扫过网格会持续触发:
- 弹层创建和销毁
- 浮层定位计算
- portal 层级更新
- React 状态和浏览器重绘
在大量图片缩略图上,这些成本会叠加成明显抖动。
经验:
- 卡片列表中的非关键提示优先用原生 `title` 或静态文案。
- `Tooltip` 适合低密度工具栏,不适合高密度素材网格的每个子元素。
- 不可见的 overlay 也要注意鼠标命中,必要时加 `pointer-events: none`
### 2. hover 样式要避免扩大绘制范围
素材卡片 hover 时如果同时使用大阴影、透明背景、`backdrop-filter` 和图片内容,浏览器需要频繁重新合成图层。
经验:
- 高密度列表 hover 优先保留轻量 `border-color`、背景色或图标显隐。
- 谨慎在列表项内使用 `backdrop-filter`
- 卡片容器可加 `contain: layout paint`,把布局和绘制影响限制在卡片内部。
### 3. 固定 WinBox id 会制造偶发标题和层级问题
素材库有多个入口,部分页面可能同时挂载多个 `MediaLibraryModal`。如果组件内部固定传 `id="media-library"`,会导致:
- DOM id 重复
- WinBox 实例状态互相覆盖
- 窗口管理器注册/注销错配
- 标题栏和 z-index 出现偶发异常
经验:
- 可复用弹窗组件不要在内部写死窗口 id。
- 需要稳定 id 时,由调用方按业务场景传入唯一值。
- 没有强需求时,让窗口封装生成内部唯一 id。
## 推荐规则
1. 素材网格内的 hover 交互要按“高频路径”设计。
- 少建弹层。
- 少用模糊和大阴影。
- 少触发跨层级定位。
2. 列表项视觉反馈不能引发布局变化。
- 边框要配合 `box-sizing: border-box`
- hover 不改变 item 尺寸。
- overlay 不参与鼠标命中。
3. 虚拟滚动只解决“渲染数量”,不解决“单项 hover 成本”。
- 可见区域仍可能有几十个媒体卡片。
- 单项效果越重,鼠标移动时越容易卡。
4. WinBox 类弹窗要避免实例身份冲突。
- 弹窗 id 是实例身份,不是功能名称。
- 多入口、多实例场景必须唯一。
- 标题图标优先用封装提供的 `icon` 插槽,不要用空的自定义标题内容挤占标题布局。
## 修复检查清单
- 鼠标扫过素材网格时,卡片只做轻量视觉变化。
- 素材名称、同步角标、缓存角标不再批量触发自定义 Tooltip。
- 卡片 hover 不改变布局尺寸,不影响相邻项。
- 弹窗组件没有固定复用同一个 WinBox id。
- 标题栏标题显式保持可见,图标和标题各走自己的插槽。