Skip to content

perf: add skeleton for tabs and chat in homepage #8246

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 18 commits into
base: main
Choose a base branch
from

Conversation

EurFelux
Copy link
Contributor

@EurFelux EurFelux commented Jul 17, 2025

What this PR does

由于现在应用常有渲染卡顿的问题,同时渲染速度不是很好优化,计划使用skeleton优化组件渲染过程的用户体验

  • 使用skeleton优化TopicsTab重新渲染时的用户体验
  • 使用skeleton优化Messages重新渲染时的用户体验
  • 延后输入栏中工具栏的渲染以增加响应速度
  • 优化从其他页面切换到HomePage时的性能
  • 修复了当切换助手时自动切换到TopicsTab后,话题会来不及刷新导致旧数据残留的问题
  • 修复了悬浮窗的HomeTabs会出现双滚动条的问题
  • 修复了悬浮窗的HomeTabs加载的话题列表为空的问题
image

在长对话场景下,切换page的响应速度能达到原来的两倍左右。(⬅️开发,➡️生产,同一话题数据)
image

感觉开发环境更卡一些,生产环境应该还能更快。

相关issues:#8237 #8217

Fixes #8303

Why we need it and why it was done in this way

The following tradeoffs were made:

悬浮窗如果不设置一个固定的height,话题的虚拟列表就无法正常加载。设置固定height会导致话题少的时候整个悬浮窗还是挺高,不能适应内容。

The following alternatives were considered:

Links to places where the discussion took place:

Breaking changes

If this PR introduces breaking changes, please describe the changes and the impact on users.

Special notes for your reviewer

Checklist

This checklist is not enforcing, but it's a reminder of items that could be relevant to every PR.
Approvers are expected to review this list.

Release note


EurFelux added 2 commits July 17, 2025 22:17
使用React的useTransition实现平滑过渡,在话题列表排序时显示骨架屏加载状态
使用React的useTransition实现平滑过渡,在消息加载时显示骨架屏
添加MessageSkeleton组件展示加载状态
@EurFelux EurFelux marked this pull request as ready for review July 17, 2025 15:07
@EurFelux EurFelux changed the title feat: add skeleton for tabs and chat feat: add skeleton for tabs and chat in homepage Jul 17, 2025
EurFelux added 3 commits July 18, 2025 05:13
在获取到有效消息前,空数组多次触发effect导致UI闪烁。添加条件分支处理空数组情况
@beyondkmp
Copy link
Collaborator

不错,速度提升了,内存占用会增加吗?

@0xfullex
Copy link
Collaborator

skeleton作为加载中的提示,不适合太密铺满

image

@beyondkmp
Copy link
Collaborator

测试了,效果不错。内存和cpu都没有涨。very good.

调整TopicsTab和Messages组件的骨架屏显示效果
- 减少TopicsTab的骨架屏线条数量
- 优化Messages骨架屏的段落宽度和间距
- 移除多余的MessageSkeleton实例
Comment on lines 438 to 467

useEffect(() => {
const updateTopics = () => {
if (pinTopicsToTop) {
setDisplayedTopics(
[...assistant.topics].sort((a, b) => {
if (a.pinned && !b.pinned) return -1
if (!a.pinned && b.pinned) return 1
return 0
})
)
} else {
setDisplayedTopics(assistant.topics)
}
}

if (isFirstRender) {
startTransition(() => {
updateTopics()
})
setIsFirstRender(false)
} else {
updateTopics()
}
return assistant.topics
}, [assistant.topics, pinTopicsToTop])
}, [assistant.topics, isFirstRender, pinTopicsToTop])

// FIXME: 如果添加其他transition会导致skeleton重新显示
if (isPending) {
return <TopicsSkeleton></TopicsSkeleton>
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

topicstab 还有必要用 skeleton 吗?反复在assistants tab 和 topics tab 之间切换每次都会看到一闪而过的 skeleton

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

topics渲染占用不少时间,这里能优化切换page的响应时间。但在page中切换tab也会触发重渲染。props又有复杂对象,memo也用不了,切换tab会闪一下的问题不好解决啊。

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

topics 现在是虚拟列表了还会占用很多时间吗?应该只会渲染可见的那些?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

我这本地测试大概用36ms渲染,不少了

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

而且不知为何DraggableVirtualList有多次渲染和提交的过程,实际响应时间大概60~70ms左右

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

会卡顿吗?开发模式?开着开发工具肯定是会慢的

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

main分支,开发模式(关闭开发工具):
https://github.com/user-attachments/assets/001d3bc0-89d1-4619-93a5-317d3a43b05e

skeleton 确实能改善体验,不过能消除闪烁就更好了,可以在话题数量比较多的时候才出现?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

加了最小显示时间,不会突兀地闪烁了

@alephpiece
Copy link
Collaborator

Cherry.Studio.2025-07-18.mp4

添加isFirstRender状态变量以区分首次渲染和后续更新
避免因多次触发重渲染导致的UI闪烁问题
Copy link
Collaborator

@0xfullex 0xfullex left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

发送消息后,skeleton和对话消息会切换闪动几次

@0xfullex
Copy link
Collaborator

[7dc4d96](/CherryHQ/cherry-studio/pull/8246/commits/7dc4d961f47ae63ccaaecb6c6f8666114dc06177)

更新 7dc4d96 后,新建话题,首次发消息,skeleton会闪动一次

移除空消息数组时的处理,避免发送第一条消息时触发skeleton
将isFirstRender加入骨架屏显示条件
@EurFelux
Copy link
Contributor Author

[7dc4d96](/CherryHQ/cherry-studio/pull/8246/commits/7dc4d961f47ae63ccaaecb6c6f8666114dc06177)

更新 7dc4d96 后,新建话题,首次发消息,skeleton会闪动一次

修复了

@EurFelux
Copy link
Contributor Author

bcfdf73这个解决方案有问题,我再看看怎么改

@0xfullex
Copy link
Collaborator

现在在短对话间切换,也出现skeleton一闪而过(本身加载速度就很快了,其实不需要skeleton。

有没有可能判断下条数,条数较少的就不显示skeleton了

@alephpiece
Copy link
Collaborator

现在在短对话间切换,也出现skeleton一闪而过(本身加载速度就很快了,其实不需要skeleton。

有没有可能判断下条数,条数较少的就不显示skeleton了

消息条数也不可靠😂有的消息很长,包含大量 mcp 调用、代码、图片,渲染一个比渲染好几个纯文字的时间还长

@EurFelux
Copy link
Contributor Author

给skeleton设置一个最小显示时间?这样不会闪,但总是要显示一小段时间

@0xfullex
Copy link
Collaborator

0xfullex commented Jul 18, 2025

给skeleton设置一个最小显示时间?这样不会闪,但总是要显示一小段时间

延时显示最小显示时间都加上吧。

延时显示,试试200ms。超过这个时间数据未好,则显示skeleton。
最小显示时间,试试500ms。skeleton一旦显示了,至少显示500ms。

实际值要测试看看肉眼效果,目标是让人觉得自然而不闪

@0xfullex 0xfullex added this to the v1.5.2 milestone Jul 18, 2025
EurFelux added 2 commits July 18, 2025 20:59
优化消息加载逻辑,通过添加pendingCount状态跟踪处理次数,避免首次渲染时的UI闪烁
添加骨架屏延迟显示功能,当加载时间小于SKELETON_DELAY_TIME时直接显示内容,否则延迟显示骨架屏
@EurFelux
Copy link
Contributor Author

给skeleton设置一个最小显示时间?这样不会闪,但总是要显示一小段时间

延时显示最小显示时间都加上吧。

延时显示,试试200ms。超过这个时间数据未好,则显示skeleton。 最小显示时间,试试500ms。skeleton一旦显示了,至少显示500ms。

实际值要测试看看肉眼效果,目标是让人觉得自然而不闪

按你说的做了一版,感觉体验怪怪的。时间还得调整一下

@0xfullex
Copy link
Collaborator

给skeleton设置一个最小显示时间?这样不会闪,但总是要显示一小段时间

延时显示最小显示时间都加上吧。
延时显示,试试200ms。超过这个时间数据未好,则显示skeleton。 最小显示时间,试试500ms。skeleton一旦显示了,至少显示500ms。
实际值要测试看看肉眼效果,目标是让人觉得自然而不闪

按你说的做了一版,感觉体验怪怪的。时间还得调整一下

对,要肉眼细调一下

@EurFelux EurFelux changed the title feat: add skeleton for tabs and chat in homepage perf: add skeleton for tabs and chat in homepage Jul 18, 2025
EurFelux added 5 commits July 18, 2025 22:56
调整skeleton显示时间与显示skeleton的延时;
调整渲染内容
将骨架屏最小显示时间从300ms减少到150ms
移除首次渲染的特殊处理逻辑,统一使用骨架屏状态控制
@Pleasurecruise
Copy link
Collaborator

是否要考虑基于简洁和气泡两种消息样式的骨架

@EurFelux
Copy link
Contributor Author

是否要考虑基于简洁和气泡两种消息样式的骨架

考虑过,觉得不是很有必要

将状态变量maxHeight重命名为height以更准确反映用途
移除click触发方式并调整悬浮延迟
修改PopoverContent样式为flex布局并使用height属性
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[错误]: 侧边栏悬浮窗弹出速度缓慢且显示错误
6 participants