You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

5.0 KiB

分镜看板性能优化实施记录

日期: 2026-02-08 类型: 性能优化 影响范围: 分镜看板模块

概述

实施了基于 orderIndex 的分镜看板性能优化方案(ADR 003),通过骨架数据 + 分页加载 + 虚拟滚动的架构,解决了大规模分镜(200+)的性能问题。

背景

当前分镜看板 API 一次性返回所有分镜数据,当项目包含 200+ 分镜时:

  • 首次加载慢(2-5秒)
  • 数据传输量大(300-500 KB)
  • 内存占用高
  • 滚动性能差

实施方案

采用 orderIndex-based + 虚拟滚动 架构:

骨架数据 (5-10 KB)
    ↓
虚拟滚动计算 (itemPositions, visibleRange)
    ↓
分页数据加载 (按 visibleRange 加载)
    ↓
渲染可见分镜

实施内容

1. 后端实现

1.1 骨架数据接口

文件: server/app/api/v1/storyboard_board.py

GET /api/v1/projects/{project_id}/storyboard-board/skeleton

响应:

{
  "projectId": "xxx",
  "storyboardCount": 200,
  "tracks": [{
    "type": "storyboard",
    "items": [
      {
        "id": "xxx",
        "orderIndex": 0,
        "duration": 3.0
      }
    ]
  }]
}

数据量: 200 分镜 ≈ 5-10 KB

1.2 分页数据接口

文件: server/app/api/v1/storyboard_board.py

GET /api/v1/projects/{project_id}/storyboard-board/paginated
  ?startIndex=0
  &endIndex=49
  &trackTypes=storyboard

响应:

{
  "items": [{
    "id": "xxx",
    "type": "storyboard",
    "orderIndex": 0,
    "duration": 3.0,
    "data": {
      "title": "分镜 1",
      "thumbnail_url": "...",
      "resources": {...}
    }
  }]
}

数据量: 50 分镜 ≈ 25-30 KB

2. 前端实现

2.1 类型定义

文件: client/src/types/storyboard-board.ts

新增类型:

  • StoryboardBoardSkeletonItem
  • StoryboardBoardSkeletonTrack
  • StoryboardBoardSkeletonData
  • StoryboardBoardPaginatedItem
  • StoryboardBoardPaginatedData

2.2 API 客户端

文件: client/src/services/api/storyboard-board.ts

新增方法:

  • getSkeleton(projectId): 获取骨架数据
  • getPaginated(projectId, startIndex, endIndex, trackTypes): 获取分页数据

2.3 React Query Hooks

文件: client/src/hooks/api/useStoryboardBoard.ts

新增 Hooks:

  • useStoryboardBoardSkeleton: 骨架数据查询
  • useStoryboardBoardPaginated: 分页数据查询

缓存策略:

  • staleTime: 5 分钟
  • cacheTime: 10 分钟
  • keepPreviousData: true(避免闪烁)

2.4 虚拟滚动辅助 Hook

文件: client/src/hooks/useStoryboardBoardVirtualScroll.ts

核心功能:

  • itemPositions: 计算每个分镜的位置和宽度(基于 orderIndex + duration)
  • calculateVisibleRange: 根据滚动位置计算可见范围
  • calculateScrollToStoryboard: 计算跳转到指定分镜的滚动位置
  • totalWidth: 计算总宽度

2.5 业务逻辑集成

文件: client/src/hooks/useStoryboardBoardLogic.ts

改动:

  • 导入骨架数据和分页数据 Hooks
  • 导入虚拟滚动辅助 Hook
  • 优先使用骨架数据计算总时长
  • 导出虚拟滚动功能到返回值

性能目标

指标 当前 目标 状态
首次加载时间 2-5s <300ms 架构就绪
骨架数据量 300-500 KB <10 KB 已实现
分页数据量 - <30 KB 已实现
内存占用 随分镜数增长 恒定 ~50 MB 待测试
滚动 FPS 30-40 60 待测试
跳转定位时间 - <100ms 已实现
支持分镜数 <200 1000+ 待测试

架构优势

  1. 数据量优化: 骨架数据仅 5-10 KB,相比完整数据减少 95%+
  2. 按需加载: 仅加载可见范围的分镜数据
  3. 快速定位: 基于 orderIndex 直接计算位置,无需遍历
  4. 可扩展性: 支持大规模数据(1000+ 分镜)
  5. 向后兼容: 保留完整数据加载作为 fallback

下一步工作

必须完成

  1. 组件层面集成: 在 StoryboardBoardPanel 中实现滚动监听和分页加载
  2. 性能测试: 使用 200+ 分镜项目测试性能指标
  3. 用户体验优化: 加载状态、错误处理、预加载策略

可选优化

  1. 预加载策略: 预加载相邻范围的数据
  2. 缓存优化: 根据使用模式调整缓存策略
  3. 虚拟滚动优化: 使用 react-window 进一步优化渲染性能

参考文档

相关文件

后端

  • server/app/schemas/storyboard_board.py
  • server/app/services/storyboard_board_service.py
  • server/app/api/v1/storyboard_board.py

前端

  • client/src/types/storyboard-board.ts
  • client/src/services/api/storyboard-board.ts
  • client/src/hooks/api/useStoryboardBoard.ts
  • client/src/hooks/useStoryboardBoardVirtualScroll.ts
  • client/src/hooks/useStoryboardBoardLogic.ts