Skip to content

Latest commit

 

History

History
138 lines (112 loc) · 3.79 KB

File metadata and controls

138 lines (112 loc) · 3.79 KB

滚动体验问题修复

修复的问题

问题1:Indicator频繁闪烁

现象:在streaming初期,indicator会频繁出现再消失,2s后才稳定

原因分析

  • 每次appendStreamChunk都会调用#smartScroll()
  • 内容高度变化导致滚动位置判断不稳定
  • 没有防抖机制,导致频繁的状态切换

修复方案

  1. 添加距离检查:如果距离底部小于20px,认为已经在底部,不需要滚动
  2. 状态变化检查:只有在状态真正发生变化时才更新
  3. 防抖机制:indicator显示/隐藏添加100ms防抖

问题2:内容更新完毕时强制滚动

现象:手动滚动后,内容更新完毕时仍会自动滚动到底部

原因分析

  • finishStreamMessage()直接调用scrollToBottom(),没有考虑用户状态
  • 没有遵循智能滚动逻辑

修复方案

  • finishStreamMessage()中的scrollToBottom()改为#smartScroll()
  • 确保遵循用户的滚动偏好

具体修复内容

1. 智能滚动优化

#smartScroll() {
  // 如果用户正在滚动,不要自动滚动
  if (this.#userScrolling) {
    this.#showNewContentIndicator();
    return;
  }

  // 检查是否真的需要滚动(避免频繁的滚动操作)
  const { scrollTop, scrollHeight, clientHeight } = this.#container;
  const distanceFromBottom = scrollHeight - (scrollTop + clientHeight);
  
  // 如果距离底部小于20px,认为已经在底部,不需要滚动
  if (distanceFromBottom < 20) {
    this.#hideNewContentIndicator();
    return;
  }

  // 如果启用了自动滚动,则滚动到底部
  if (this.#autoScroll) {
    this.scrollToBottom();
    this.#hideNewContentIndicator();
  } else {
    // 否则显示新内容提示
    this.#showNewContentIndicator();
  }
}

2. 状态变化检查

#checkScrollPosition() {
  const { scrollTop, scrollHeight, clientHeight } = this.#container;
  const distanceFromBottom = scrollHeight - (scrollTop + clientHeight);
  
  // 如果距离底部小于50px,认为用户在关注底部内容
  if (distanceFromBottom < 50) {
    // 只有在状态发生变化时才更新
    if (!this.#autoScroll) {
      this.#enableAutoScroll();
      this.#hideNewContentIndicator();
    }
  } else {
    // 只有在状态发生变化时才更新
    if (this.#autoScroll) {
      this.#disableAutoScroll();
    }
  }
}

3. Indicator防抖机制

#showNewContentIndicator() {
  if (this.#newContentIndicator) {
    // 防抖处理:避免频繁显示/隐藏
    if (this.#indicatorTimeout) {
      clearTimeout(this.#indicatorTimeout);
    }
    
    this.#indicatorTimeout = setTimeout(() => {
      if (this.#newContentIndicator) {
        this.#newContentIndicator.style.display = 'flex';
      }
    }, 100);
  }
}

4. 完成时智能滚动

finishStreamMessage() {
  // ... 其他逻辑 ...
  
  // 智能滚动:只在用户没有禁用自动滚动时才滚动
  this.#smartScroll();
}

优化效果

修复前的问题

  • ❌ Indicator频繁闪烁,体验差
  • ❌ 手动滚动后仍被强制滚动到底部
  • ❌ 没有防抖机制,性能不佳

修复后的效果

  • ✅ Indicator稳定显示,不再闪烁
  • ✅ 尊重用户的滚动偏好
  • ✅ 添加防抖机制,性能优化
  • ✅ 更精确的滚动位置判断

技术细节

距离阈值说明

  • 20px:用于判断是否已经在底部,避免不必要的滚动
  • 50px:用于判断用户是否在关注底部内容

防抖时间

  • 滚动检测:150ms防抖
  • Indicator显示:100ms防抖

状态管理

  • 只有在状态真正发生变化时才更新
  • 避免频繁的DOM操作和样式切换

这些修复大大改善了streaming聊天的滚动体验,让用户能够更舒适地控制阅读节奏。