Files
TrueGrowth/docs/MEDIA_LIBRARY_RENDER_PERFORMANCE_LESSONS.md

3.1 KiB
Raw Blame History

素材库渲染性能经验

更新日期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。
  • 标题栏标题显式保持可见,图标和标题各走自己的插槽。