perf(tabs): release stale image and tab state
Pixel 10 APK / build (push) Successful in 37m12s

This commit is contained in:
Codex
2026-08-10 17:59:50 +02:00
parent 03227320f4
commit aab2bc0cee
10 changed files with 203 additions and 8 deletions
@@ -36,6 +36,7 @@ import 'package:weblibre/features/geckoview/domain/entities/states/translation.d
import 'package:weblibre/features/geckoview/domain/providers.dart';
import 'package:weblibre/features/geckoview/domain/providers/selected_tab.dart';
import 'package:weblibre/features/geckoview/domain/providers/tab_detail_state.dart';
import 'package:weblibre/features/geckoview/domain/providers/tab_list.dart';
import 'package:weblibre/features/geckoview/features/find_in_page/domain/repositories/find_in_page.dart';
import 'package:weblibre/features/geckoview/features/tabs/data/entities/isolation_context.dart';
import 'package:weblibre/features/geckoview/features/tabs/data/entities/tab_mode.dart';
@@ -75,6 +76,14 @@ class TabStates extends _$TabStates {
state = {...state}..[tabId] = next;
}
void _removeAll(Set<String> tabIds) {
if (!state.keys.any(tabIds.contains)) {
return;
}
state = {...state}..removeWhere((tabId, _) => tabIds.contains(tabId));
}
Future<void> _onTabContentStateChange(TabContentState contentState) async {
final current = await patchedState(contentState.id);
@@ -187,6 +196,9 @@ class TabStates extends _$TabStates {
bytes,
targetWidth: thumbnailDecodeWidth,
allowUpscaling: false,
// Periodic screenshots are almost always unique. Caching each decode
// retained up to 100 obsolete GPU images in the global icon LRU.
cacheResult: false,
),
);
@@ -415,6 +427,29 @@ class TabStates extends _$TabStates {
},
);
ref.listen(tabListProvider, (previous, next) {
if (previous == null) {
// The first list can be a partial restore snapshot. There is no reliable
// removal signal until Gecko has emitted at least two snapshots.
return;
}
final activeTabIds = next.value.toSet();
final removedTabIds = previous.value
.where((tabId) => !activeTabIds.contains(tabId))
.toSet();
if (removedTabIds.isEmpty) {
return;
}
_removeAll(removedTabIds);
ref.read(tabProgressStatesProvider.notifier).removeAll(removedTabIds);
ref.read(tabThumbnailsProvider.notifier).removeAll(removedTabIds);
ref.read(tabHistoryStatesProvider.notifier).removeAll(removedTabIds);
ref.read(tabFindResultStatesProvider.notifier).removeAll(removedTabIds);
ref.read(tabTranslationStatesProvider.notifier).removeAll(removedTabIds);
});
ref.onDispose(() async {
for (final sub in subscriptions) {
await sub.cancel();