Skip to content

perf: 优化冷启动速度与渲染性能,修复多项体验问题 - #22

Merged
Re-BeiChen merged 1 commit into
SPlayer-Dev:devfrom
Shomi-FJS:pre-fix
May 21, 2026
Merged

Re-BeiChen merged 1 commit into
SPlayer-Dev:devfrom
Shomi-FJS:pre-fix

Conversation

@Shomi-FJS

Copy link
Copy Markdown

📌 变更类型

  • ✨ feat — 新功能
  • 🐞 fix — Bug 修复
  • 🎨 style — 仅样式 / 格式,不影响逻辑
  • ♻️ refactor — 重构,不改变外部行为
  • ⚡ perf — 性能优化
  • 📝 docs — 仅文档
  • 🧪 test — 新增 / 修改测试
  • 🔧 chore — 构建 / 脚本 / 依赖
  • 🚀 ci — 仅 CI 配置
  • ⏪ revert — 回滚

📝 变更说明

围绕冷启动到首播的关键路径与切歌时主线程阻塞做一组组合优化与对应 Bug 修复,主要包含:

性能优化

  1. localforage 实例延迟初始化:music-data / user-data / background-data 三个 IndexedDB 实例改为按需懒加载(getMusicDB() / getUserDB() / getBackgroundDB()),避免模块解析阶段就建立 IDB 连接拖慢冷启动。
  2. Electron 初始化逻辑重构:initIpc / sendRegisterProtocol / useSettingStore 改为按需 import() 异步加载,并加 .catch 错误捕获,确保 Android / Web 路径不再无谓加载 Electron 专属模块。
  3. 播放队列真懒加载:SongPlayList 抽屉用 defineAsyncComponent + v-if="hasMountedPlayList" 在用户首次打开时才挂载(先前的 <Suspense> 写法实际只拆 chunk 不延迟挂载),首挂载后保持常驻避免 n-drawer 入场动画重置。
  4. 封面取色优化:
    • 采样尺寸 50×50 → 32×32,QuantizerCelebi.quantize 工作量降至约 40%;
    • 新增 URL → 主题 LRU 缓存(上限 64 条),重复封面/历史回放零计算;
    • 取色重活继续放在 requestIdleCallback 中,避免阻塞切歌首帧渲染。
  5. 启动后置任务:版本打印、用户协议、自动关闭计时器、Electron 快捷键 / 任务栏 / Mac 状态栏歌词 / 更新检查等非关键任务通过 runAfterStartup 推到下一帧执行,减小首屏 onMounted 同步压力。

Bug 修复 / 健壮性

  1. syncAndroidPlaybackContext 脏数据守卫:在每次 await IPC 之间检查"歌曲是否还是初始那一首",无论是否传入 songOverride 都做守卫;用户在 await 间隙切歌时不再把旧歌的元数据 / 队列上下文写入 Native,并补上整体 try/catch 防御 IPC 异常。
  2. 修复并发写入丢失:
    • 新增 isLoadingData + dirtyMusicKeys / dirtyUserKeys 脏标记机制,加载期间用户触发的 setPlayList 等写操作不会被随后到达的旧值 getItem 覆盖;
    • addDownloadingSong / removeDownloadingSong / markDownloadFailed 改为 async 并 await setItem,避免 fire-and-forget 在 App 后台时丢写。
  3. 样式精简:从主 bundle 中移除全局 github-markdown-css/github-markdown.css 引入,改为按使用组件局部加载,缩减主 bundle 体积。

🔗 关联 Issue

Closes #

📱 影响范围

  • 🎵 播放引擎 / 音频
  • 📝 歌词 / 桌面歌词
  • 🔔 通知栏 / MediaSession
  • 🌐 在线音乐 (网易云 / Jellyfin / Navidrome / Emby / Subsonic / Last.fm)
  • 🧩 内置 API (nodejs-mobile)
  • 🎨 UI / 主题 / 布局
  • 📦 构建 / 打包 / 签名
  • 📱 Capacitor / 原生 Android 代码
  • 📄 文档 / README

✅ 自检清单

  • 本 PR 目标分支为 dev
  • 本地已执行 pnpm lint 且无 warning
  • 本地已执行 pnpm typecheck 且无报错
  • 已在 至少一台真机 上构建并验证关键路径
  • UI 改动已兼顾 手机竖屏 + 平板横屏 两种布局
  • 新增 / 修改的文案使用中文,与项目整体风格一致
  • 未引入不必要的依赖 / 大体积资源
  • 未修改签名密钥 / CI Secrets 相关文件

🧪 测试方式

  1. 冷启动 → 首播:杀掉应用,重新打开,观察从启动到歌曲发声的耗时与中途是否有空白卡顿。
  2. 快速进入 /like、/history:首屏进来后立即点击"我的喜欢" / "历史"页,确认列表数据立刻显示,没有 0.2s 空状态闪烁。
  3. 重复封面播放:播放同一专辑多首歌或重复历史歌曲,确认主题色应用即时(缓存命中)。
  4. 播放队列首次打开:点击播放队列按钮,确认抽屉正常拉起;多次开关动画无异常。

💬 其他说明 (选填)

  • 取色优化采用了采样减小 + URL 缓存 + idleCallback 三件套的轻量方案,足以缓解大多数场景的卡顿;如果后续仍有重负载场景,可进一步引入 Web Worker 把 quantize 移出主线程。

1.  延迟初始化localforage实例,避免模块解析阻塞冷启动
2.  重构Electron初始化逻辑,按需异步加载模块并添加错误捕获
3.  实现播放队列懒加载,减少初始渲染资源占用
4.  优化封面取色逻辑:降低采样尺寸、添加缓存、调度到空闲帧执行
5.  重构Android播放上下文同步逻辑,添加脏数据守卫与错误处理
6.  拆分初始化非关键任务到启动后执行,缩短首屏渲染时间
7.  修复本地数据加载并发写入覆盖问题,优化数据加载逻辑
8.  移动全局markdown样式到对应组件,减少主bundle体积
@Re-BeiChen
Re-BeiChen merged commit 2afd801 into SPlayer-Dev:dev May 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants