# 素材库渲染性能经验 更新日期: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。 - 标题栏标题显式保持可见,图标和标题各走自己的插槽。