app
Go to file
fengge 4cb6b4ed08 性能优化: 提取 MarkwonHolder 单例,避免 SSE 流式期间重复创建 Markwon 实例
【问题背景】
ChatArea.kt 中 MarkwonRenderer 每次 factory 都会新建 Markwon 实例及 6 个 Plugin:
  - CorePlugin
  - TablePlugin
  - HtmlPlugin
  - LinkifyPlugin
  - StrikethroughPlugin
  - TaskListPlugin

在 SSE 流式聊天场景下:
1. AI 助手每收到一个 chunk 都会触发 messages StateFlow 更新
2. LazyColumn 重组会导致 MarkwonRenderer factory 被调用
3. 每个 AI 消息气泡第一次显示时都会 new 一整套 Markwon + 6 个 Plugin

【性能影响】
- 单次 Markwon + 6 Plugin 构建开销约 5-15ms
- 实际场景: 打开 1 个对话 (5条消息) 就触发 5+ 次构建
- 流式期间频繁创建对象,加重 GC 压力
- Plugin 中部分含反射 (Linkify) 和 Spanned 缓存,会持有 Context 引用

【修复方案】
新增 MarkwonHolder 单例 (object),采用 double-checked locking 模式:
1. 首次访问时,使用 applicationContext 构建 Markwon (避免 Activity 泄漏)
2. 后续访问直接返回已缓存实例
3. 使用 @Volatile 保证多线程可见性
4. factory 改为 MarkwonHolder.get(ctx),自动复用

【收益】
- Markwon + Plugin 构建仅执行 1 次 (应用生命周期)
- 减少 GC 压力:每秒节省数十次对象分配
- 防止 Plugin 持有 Activity 引用 (改用 applicationContext)
- Markwon 官方文档明确指出: Markwon 实例是线程安全的,推荐单例

【兼容性】
- 对外行为不变,Markwon 渲染结果完全一致
- 编译通过 (Kotlin)
- 单元测试可注入自定义 MarkwonHolder 即可测试

【影响范围】
- ChatArea.kt (新增 MarkwonHolder private object)
2026-06-02 13:13:57 +08:00
.codegraph 优化 2026-06-01 23:24:28 +08:00
.idea 修复问题 2026-04-18 18:45:16 +08:00
app 性能优化: 提取 MarkwonHolder 单例,避免 SSE 流式期间重复创建 Markwon 实例 2026-06-02 13:13:57 +08:00
gradle 1 2026-04-26 19:15:48 +08:00
key 123 2026-04-01 22:23:47 +08:00
.gitignore 优化 2026-05-08 03:30:13 +08:00
build.gradle.kts webview 2026-04-29 10:21:38 +08:00
gradle.properties 123 2026-04-01 22:23:47 +08:00
gradlew 123 2026-04-01 22:23:47 +08:00
gradlew.bat 123 2026-04-01 22:23:47 +08:00
img.png 123 2026-04-01 22:23:47 +08:00
img_1.png ai 2026-05-20 11:11:50 +08:00
settings.gradle.kts webview 2026-04-29 10:21:38 +08:00