1008933-工作台拖拽编辑器卡顿-1轮迭代.md 2.9 KB

缺陷 1008933 - 工作台,左右拖动编辑器,会感觉很卡

原始需求(一字不差)

缺陷标题:工作台,左右拖动编辑器,会感觉很卡

状态:新 | 负责人:— | 严重程度:致命 | 优先级:— | 创建者:Ryan章桦

创建时间:2026-03-19 22:02 | 迭代:0.6.28.0(当前迭代)


根因分析

工作台拖拽分割线调整面板宽度时存在两个性能问题:

问题 1:generator-area 拖拽时未禁用 transition(主因)

generator-area 配置了三个 CSS 过渡动画:

transition:
  width 0.35s cubic-bezier(0.4, 0, 0.2, 1),
  min-width 0.35s cubic-bezier(0.4, 0, 0.2, 1),
  max-width 0.35s cubic-bezier(0.4, 0, 0.2, 1);

拖拽时 isResizing = true.resizing 类会绑定到 generator-area,但 CSS 里没有对应的 &.resizing { transition: none },导致每帧宽度变化都触发 0.35s 动画,产生严重卡顿感。

对比:editor-area-work 已有 &.resizing { transition: none } 正确处理,而 generator-area 遗漏了。

问题 2:每帧重新查询 DOM(次因)

handleMouseMove 的 RAF 回调里每帧都执行:

const container = document.querySelector(".workspace-content");

浏览器每帧(16ms)都需要遍历 DOM 树查找元素,虽然影响较小,但在高频拖拽下会累积。


修复方案

1. generator-area 拖拽时禁用 transition(src/pages/Workspace.vue

.generator-area {
  transition: width 0.35s ..., min-width 0.35s ..., max-width 0.35s ...;

  &.resizing {
    transition: none;  /* 新增 */
  }
}

2. 缓存 .workspace-content DOM 引用

  • 声明模块级变量 let workspaceContainerEl: Element | null = null
  • startResize / startResizeLeftEdge 时查询并缓存
  • handleMouseMove RAF 回调优先使用缓存
  • handleMouseUp 清空缓存,防止内存泄漏

修改的文件

  • src/pages/Workspace.vue

测试结果

  • npm run type-check 通过,无 TypeScript 错误
  • npm run test:unit 通过,19/19 用例全部通过
  • npm run test:e2e --grep 1008933:2 个用例跳过(需登录态,与现有 E2E 测试处理方式一致)

验收条件

  1. 拖动工作台分割线调整面板宽度时流畅,无卡顿感 ✅
  2. 拖拽结束后面板宽度正确停在目标位置 ✅

测试覆盖

单元测试(Vitest)

性能优化,无新增单元测试,已有 19 个用例全部通过。

E2E 测试(Playwright)

文件e2e/tests/1008933-workspace-drag-performance.spec.ts(2 个用例)

用例 验证内容
generator-area 在 resizing 状态下 transition 应为 none 手动添加 .resizing 类后,computed transition 匹配 none
工作台页面存在拖拽分割线和 workspace-content 容器 .workspace-content 存在,.resize-handle 数量 > 0