6.7 KiB
6.7 KiB
重复事件上报修复 - 验证指南
修复版本: V2 修复日期: 2025-12-05
快速验证步骤
方法 1: 浏览器控制台检查 ⭐ 推荐
-
打开应用的浏览器控制台(F12)
-
运行以下代码检查事件监听器数量:
// 检查 click 事件监听器
const listeners = getEventListeners(document.body);
console.log('📊 Click listeners count:', listeners.click?.length);
// 预期输出: 1
// 如果 > 1,说明还有重复问题
- 结果判断:
- ✅
listeners.click.length === 1→ 修复成功 - ❌
listeners.click.length > 1→ 仍有问题,请重启应用
- ✅
方法 2: 启用调试日志
-
找到
packages/drawnix/src/drawnix.tsx文件 -
修改 plugins 配置,启用 devMode:
const plugins: PlaitPlugin[] = [
withDraw,
withGroup,
withMind,
withMindExtend,
withCommonPlugin,
buildDrawnixHotkeyPlugin(updateAppState),
withFreehand,
buildPencilPlugin(updateAppState),
buildTextLinkPlugin(updateAppState),
withVideo,
// ⬇️ 修改这一行,添加配置
(editor) => withTracking(editor, {
devMode: true, // 启用调试模式
logLevel: 'debug' // 显示详细日志
}),
];
-
刷新应用,点击任意按钮
-
观察控制台输出:
✅ 正常情况(修复成功):
[Tracking] ✅ Track: chat_click_drawer_close
❌ 异常情况(仍有重复):
[Tracking] ✅ Track: chat_click_drawer_close
[Tracking] ✅ Track: chat_click_drawer_close ⬅️ 重复了!
方法 3: Umami Analytics 后台验证
-
登录 Umami Analytics 后台
-
进入"实时"(Real-time)视图
-
在应用中点击一个按钮(如"收起对话")
-
观察 Umami 后台的事件流:
✅ 正常情况:
12:34:56 chat_click_drawer_close (1 次)
❌ 异常情况:
12:34:56 chat_click_drawer_close (2 次) ⬅️ 重复了!
12:34:56 chat_click_drawer_close
高级验证
验证单例模式
在控制台运行:
// 检查是否是单例
let service1, service2;
// 模拟创建多个 editor
const editor1 = { /* mock editor */ };
const editor2 = { /* mock editor */ };
// 应该共享同一个 trackingService 实例
console.log(editor1.trackingService === editor2.trackingService);
// 预期输出: true
验证防抖机制
-
启用 devMode(参考方法2)
-
快速双击任意按钮(<200ms 间隔)
-
观察控制台输出:
[Tracking] ✅ Track: toolbar_click_hand
[Tracking] 🚫 Global debounce: toolbar_click_hand (85ms ago) ⬅️ 第二次被拦截
- 正常点击(>200ms 间隔)
[Tracking] ✅ Track: toolbar_click_hand
// ... 等待 300ms ...
[Tracking] ✅ Track: toolbar_click_hand ⬅️ 第二次正常上报
验证 onClick 功能
点击各个按钮,确认功能正常:
- ✅ 聊天抽屉触发器:能正常打开/关闭对话框
- ✅ 工具栏按钮:能正常切换工具
- ✅ 任务队列按钮:能正常删除/重试任务
- ✅ 设置按钮:能正常保存设置
常见问题排查
问题1: 仍然有重复上报
可能原因: 应用未重启,旧的 TrackingService 实例仍在内存中
解决方法:
- 完全关闭浏览器标签页
- 重新打开应用
- 硬刷新(Ctrl + Shift + R 或 Cmd + Shift + R)
问题2: 监听器数量 > 1
可能原因: 热重载导致多个实例累积
解决方法:
// 在控制台手动重置
import { resetGlobalTrackingService } from './plugins/tracking';
resetGlobalTrackingService();
location.reload();
问题3: onClick 不工作
可能原因: 事件被其他代码阻止
检查步骤:
- 打开控制台 → Elements 标签
- 选中按钮元素
- 查看 Event Listeners
- 确认 click 事件监听器存在
问题4: 调试日志不显示
可能原因: devMode 未启用或配置未生效
检查步骤:
// 在控制台检查配置
const service = document.querySelector('.drawnix')?.__trackingService;
console.log('DevMode:', service?.config?.devMode);
// 预期输出: true
性能验证
检查内存泄漏
- 打开 Chrome DevTools → Performance 标签
- 开始录制
- 在应用中进行正常操作(点击按钮、打开对话框等)
- 停止录制
- 查看内存使用曲线
正常情况: 内存曲线平稳,有小幅波动但无持续增长
检查事件处理时间
// 在控制台测试点击响应时间
console.time('click-response');
document.querySelector('[data-track="chat_click_drawer_close"]').click();
console.timeEnd('click-response');
// 预期输出: < 5ms
回归测试清单
验证以下功能是否正常:
聊天功能
- 打开/关闭聊天抽屉
- 切换会话列表
- 新建会话
- 删除会话
- 选择模型
工具栏功能
- 切换工具(手型、选择、画笔等)
- 调整尺寸
- 选择颜色
- 缩放画布
任务队列功能
- 打开/关闭任务面板
- 预览任务结果
- 删除任务
- 重试失败任务
- 插入到画板
- 下载结果
AI 生成功能
- 图片生成
- 视频生成
- 调整参数
- 插入到画板
设置功能
- 打开设置对话框
- 保存设置
- 取消设置
验证成功标准
所有以下条件都满足,说明修复成功:
- ✅ 事件监听器数量 = 1
- ✅ 每次点击只上报 1 次事件
- ✅ onClick 功能全部正常
- ✅ 防抖机制正常工作(快速双击只上报 1 次)
- ✅ devMode 日志正常显示
- ✅ 无内存泄漏
- ✅ 响应时间 < 5ms
报告问题
如果验证失败,请提供以下信息:
- 监听器数量:
getEventListeners(document.body).click?.length - 控制台截图: 包含错误或异常日志
- Umami 截图: 显示重复事件
- 复现步骤: 详细的操作步骤
- 环境信息:
- 浏览器版本
- 操作系统
- 应用版本/分支
自动化测试(可选)
创建 Cypress/Playwright 测试:
describe('Tracking Deduplication', () => {
it('should track event only once', () => {
// 清空 Umami 事件队列
cy.window().then((win) => {
win.localStorage.removeItem('umami.cache');
});
// 点击按钮
cy.get('[data-track="chat_click_drawer_close"]').click();
// 等待上报
cy.wait(1000);
// 验证只上报了 1 次
cy.window().then((win) => {
const events = JSON.parse(win.localStorage.getItem('umami.cache') || '[]');
const clickEvents = events.filter(e => e.name === 'chat_click_drawer_close');
expect(clickEvents).to.have.length(1);
});
});
});
最后更新: 2025-12-05 文档版本: V2 适用修复: BUG_FIX_DUPLICATE_EVENTS_V2.md