From 11979b12e2f34f469a9e66b90df7ed72bfc4fd8d Mon Sep 17 00:00:00 2001 From: zarzet Date: Tue, 14 Jul 2026 11:37:46 +0700 Subject: [PATCH] perf(ui): skip the shell backdrop blur on low-end devices The sigma-18 BackdropFilter re-filters everything scrolling underneath every frame. The startup runtime profile now feeds a lowEndDevice provider; those devices get an opaque bottom bar instead. --- lib/main.dart | 6 +++++ lib/providers/runtime_profile_provider.dart | 6 +++++ lib/screens/main_shell.dart | 26 ++++++++++++++++----- 3 files changed, 32 insertions(+), 6 deletions(-) create mode 100644 lib/providers/runtime_profile_provider.dart diff --git a/lib/main.dart b/lib/main.dart index 36407f2a..1ab6b9b7 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -10,6 +10,7 @@ import 'package:spotiflac_android/providers/download_queue_provider.dart'; import 'package:spotiflac_android/providers/extension_provider.dart'; import 'package:spotiflac_android/providers/library_collections_provider.dart'; import 'package:spotiflac_android/providers/local_library_provider.dart'; +import 'package:spotiflac_android/providers/runtime_profile_provider.dart'; import 'package:spotiflac_android/providers/settings_provider.dart'; import 'package:spotiflac_android/services/notification_service.dart'; import 'package:spotiflac_android/services/platform_bridge.dart'; @@ -42,6 +43,11 @@ void main() { runApp( ProviderScope( + overrides: [ + lowEndDeviceProvider.overrideWithValue( + runtimeProfile.disableOverscrollEffects, + ), + ], child: _EagerInitialization( child: SpotiFLACApp( disableOverscrollEffects: runtimeProfile.disableOverscrollEffects, diff --git a/lib/providers/runtime_profile_provider.dart b/lib/providers/runtime_profile_provider.dart new file mode 100644 index 00000000..1966a2ef --- /dev/null +++ b/lib/providers/runtime_profile_provider.dart @@ -0,0 +1,6 @@ +import 'package:flutter_riverpod/flutter_riverpod.dart'; + +/// True on low-end hardware (arm32-only or low-RAM, resolved at startup in +/// main.dart via a ProviderScope override). UI uses it to skip expensive +/// effects like the shell's backdrop blur. +final lowEndDeviceProvider = Provider((ref) => false); diff --git a/lib/screens/main_shell.dart b/lib/screens/main_shell.dart index 19aabb56..e0e6b782 100644 --- a/lib/screens/main_shell.dart +++ b/lib/screens/main_shell.dart @@ -10,6 +10,7 @@ import 'package:spotiflac_android/l10n/l10n.dart'; import 'package:spotiflac_android/providers/download_queue_provider.dart'; import 'package:spotiflac_android/providers/settings_provider.dart'; import 'package:spotiflac_android/providers/repo_provider.dart'; +import 'package:spotiflac_android/providers/runtime_profile_provider.dart'; import 'package:spotiflac_android/providers/track_provider.dart'; import 'package:spotiflac_android/providers/preview_player_provider.dart'; import 'package:spotiflac_android/screens/home_tab.dart'; @@ -675,10 +676,9 @@ class _MainShellState extends ConsumerState ], ) : pageView, - bottomNavigationBar: ClipRect( - child: BackdropFilter( - filter: ImageFilter.blur(sigmaX: 18, sigmaY: 18), - child: Column( + bottomNavigationBar: Builder( + builder: (context) { + final bottomBar = Column( mainAxisSize: MainAxisSize.min, children: [ const MiniPlayer(), @@ -707,8 +707,22 @@ class _MainShellState extends ConsumerState ), ), ], - ), - ), + ); + // The backdrop blur re-filters everything scrolling underneath on + // every frame; low-end devices get an opaque base instead. + if (ref.read(lowEndDeviceProvider)) { + return ColoredBox( + color: settingsGroupColor(context), + child: bottomBar, + ); + } + return ClipRect( + child: BackdropFilter( + filter: ImageFilter.blur(sigmaX: 18, sigmaY: 18), + child: bottomBar, + ), + ); + }, ), ), );