perf: reduce CPU usage and unify next-track buffering settings

- Throttle audio:progress from 100ms to 500ms; WaveformSeek and
  FsSeekbar use imperative DOM updates instead of React re-renders
- Fix all usePlayerStore() calls without selectors across pages and
  components (useShallow / individual selectors throughout)
- Remove filter:blur and transform:scale from Hero, AlbumDetail and
  FullscreenPlayer backgrounds — eliminated expensive software
  compositing layers on WebKitGTK
- Replace translate3d with 2D translate in FS mesh and portrait
  animations; remove will-change:transform from mesh blobs
- Move Hot Cache section from Storage tab to Audio tab; group Preload
  and Hot Cache under a shared 'Next Track Buffering' section with a
  mutual-exclusivity note and auto-disable logic
- Add 'off' toggle to Preload (replaces Off button with toggle switch);
  enabling either method now automatically disables the other

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Psychotoxical
2026-04-10 13:38:33 +02:00
parent c9dfbcc19f
commit c49f6af38b
21 changed files with 398 additions and 271 deletions
+3
View File
@@ -571,6 +571,9 @@ export const deTranslation = {
gaplessDesc: 'Nächsten Track vorpuffern um Lücken zwischen Songs zu vermeiden',
preloadMode: 'Nächsten Track vorpuffern',
preloadModeDesc: 'Wann mit dem Puffern des nächsten Tracks begonnen werden soll',
nextTrackBufferingTitle: 'Nächster Track Pufferung',
preloadHotCacheMutualExclusive: 'Preload und Hot Cache erfüllen denselben Zweck nur eine Methode kann gleichzeitig aktiv sein. Das Aktivieren einer deaktiviert die andere automatisch.',
preloadOff: 'Aus',
preloadBalanced: 'Ausgewogen (30 s vor Ende)',
preloadEarly: 'Früh (nach 5 s Wiedergabe)',
preloadCustom: 'Benutzerdefiniert',
+3
View File
@@ -572,6 +572,9 @@ export const enTranslation = {
gaplessDesc: 'Pre-buffer next track to eliminate gaps between songs',
preloadMode: 'Preload Next Track',
preloadModeDesc: 'When to start buffering the next track in the queue',
nextTrackBufferingTitle: 'Next Track Buffering',
preloadHotCacheMutualExclusive: 'Preload and Hot Cache serve the same purpose — only one can be active at a time. Enabling one will automatically disable the other.',
preloadOff: 'Off',
preloadBalanced: 'Balanced (30 s before end)',
preloadEarly: 'Early (after 5 s of playback)',
preloadCustom: 'Custom',
+3
View File
@@ -569,6 +569,9 @@ export const frTranslation = {
gaplessDesc: 'Préparer la piste suivante pour éliminer les silences entre les morceaux',
preloadMode: 'Précharger la piste suivante',
preloadModeDesc: 'Quand commencer à mettre en mémoire tampon la piste suivante',
nextTrackBufferingTitle: 'Piste suivante mise en mémoire tampon',
preloadHotCacheMutualExclusive: "Preload et Hot Cache remplissent le même rôle — un seul peut être actif à la fois. Activer l'un désactive automatiquement l'autre.",
preloadOff: 'Désactivé',
preloadBalanced: 'Équilibré (30 s avant la fin)',
preloadEarly: 'Tôt (après 5 s de lecture)',
preloadCustom: 'Personnalisé',
+3
View File
@@ -571,6 +571,9 @@ export const nbTranslation = {
experimental: 'Eksperimentell',
preloadMode: 'Forhåndslast neste spor',
preloadModeDesc: 'Når buffering av neste spor i køen skal starte',
nextTrackBufferingTitle: 'Neste spor bufring',
preloadHotCacheMutualExclusive: 'Forhåndslasting og Hot Cache tjener samme formål bare én kan være aktiv om gangen. Å aktivere den ene deaktiverer automatisk den andre.',
preloadOff: 'Av',
preloadBalanced: 'Balansert (30 s før slutt)',
preloadEarly: 'Tidlig (etter 5 s avspilling)',
preloadCustom: 'Egendefinert',
+3
View File
@@ -569,6 +569,9 @@ export const nlTranslation = {
gaplessDesc: 'Volgend nummer vooraf bufferen om stiltes tussen nummers te elimineren',
preloadMode: 'Volgend nummer vooraf laden',
preloadModeDesc: 'Wanneer met het bufferen van het volgende nummer wordt begonnen',
nextTrackBufferingTitle: 'Volgend nummer buffering',
preloadHotCacheMutualExclusive: 'Preload en Hot Cache dienen hetzelfde doel — slechts één kan tegelijk actief zijn. Het inschakelen van de ene schakelt de andere automatisch uit.',
preloadOff: 'Uit',
preloadBalanced: 'Gebalanceerd (30 s voor einde)',
preloadEarly: 'Vroeg (na 5 s afspelen)',
preloadCustom: 'Aangepast',
+3
View File
@@ -597,6 +597,9 @@ export const ruTranslation = {
gaplessDesc: 'Заранее подгружать следующий трек, чтобы не было тишины',
preloadMode: 'Предзагрузка следующего трека',
preloadModeDesc: 'Когда начинать буферизацию следующего в очереди',
nextTrackBufferingTitle: 'Буферизация следующего трека',
preloadHotCacheMutualExclusive: 'Предзагрузка и Hot Cache выполняют одну функцию — одновременно может быть активна только одна. Включение одной автоматически отключает другую.',
preloadOff: 'Выкл.',
preloadBalanced: 'Умеренно (за 30 с до конца)',
preloadEarly: 'Рано (через 5 с после старта)',
preloadCustom: 'Свой интервал',
+3
View File
@@ -565,6 +565,9 @@ export const zhTranslation = {
gaplessDesc: '预缓冲下一首曲目以消除歌曲间的间隙',
preloadMode: '预加载下一曲目',
preloadModeDesc: '何时开始缓冲队列中的下一曲目',
nextTrackBufferingTitle: '下一曲目缓冲',
preloadHotCacheMutualExclusive: '预加载与热缓存用途相同——两者不能同时启用。启用其中一个会自动禁用另一个。',
preloadOff: '关闭',
preloadBalanced: '均衡(结束前30秒)',
preloadEarly: '提前(播放5秒后)',
preloadCustom: '自定义',