perf: riduci spazio APK e allocazioni a runtime

- Comprimi icon-only.png da 5.2 MB a 72 KB (512×512, quantizzazione 256 colori)
- Rimuovi setState() ridondante in ConverterPage.onChanged: search() chiama già notifyListeners()
- Cattura pendingItems/checkedItems in variabili locali nel build di ShoppingListPage per evitare filtraggio ripetuto a ogni paint

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-18 00:01:49 +02:00
parent ca875d29c4
commit 8d25f63f24
3 changed files with 15 additions and 18 deletions
Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 MiB

After

Width:  |  Height:  |  Size: 72 KiB

@@ -89,7 +89,6 @@ class _ConverterPageState extends State<ConverterPage> {
: null, : null,
), ),
onChanged: (v) { onChanged: (v) {
setState(() {});
context.read<ConverterProvider>().search(v); context.read<ConverterProvider>().search(v);
}, },
), ),
@@ -57,6 +57,8 @@ class _ShoppingListPageState extends State<ShoppingListPage> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
final theme = Theme.of(context); final theme = Theme.of(context);
final provider = context.watch<ShoppingListProvider>(); final provider = context.watch<ShoppingListProvider>();
final pending = provider.pendingItems;
final checked = provider.checkedItems;
return Column( return Column(
crossAxisAlignment: CrossAxisAlignment.stretch, crossAxisAlignment: CrossAxisAlignment.stretch,
@@ -73,8 +75,8 @@ class _ShoppingListPageState extends State<ShoppingListPage> {
), ),
if (provider.items.isNotEmpty) if (provider.items.isNotEmpty)
Text( Text(
'${provider.checkedItems.length} / ${provider.items.length} ' '${checked.length} / ${provider.items.length} '
'completat${provider.checkedItems.length == 1 ? 'o' : 'i'}', 'completat${checked.length == 1 ? 'o' : 'i'}',
style: theme.textTheme.bodyMedium?.copyWith( style: theme.textTheme.bodyMedium?.copyWith(
color: theme.colorScheme.onSurface.withValues(alpha: 0.6), color: theme.colorScheme.onSurface.withValues(alpha: 0.6),
), ),
@@ -124,25 +126,23 @@ class _ShoppingListPageState extends State<ShoppingListPage> {
padding: const EdgeInsets.fromLTRB(16, 0, 16, 16), padding: const EdgeInsets.fromLTRB(16, 0, 16, 16),
children: [ children: [
// Pending items // Pending items
if (provider.pendingItems.isNotEmpty) if (pending.isNotEmpty)
Card( Card(
margin: EdgeInsets.zero, margin: EdgeInsets.zero,
child: Column( child: Column(
children: [ children: [
for (int i = 0; for (int i = 0; i < pending.length; i++) ...[
i < provider.pendingItems.length;
i++) ...[
if (i > 0) if (i > 0)
const Divider( const Divider(
height: 1, indent: 16, endIndent: 16), height: 1, indent: 16, endIndent: 16),
ShoppingItemTile( ShoppingItemTile(
item: provider.pendingItems[i], item: pending[i],
onToggle: () => context onToggle: () => context
.read<ShoppingListProvider>() .read<ShoppingListProvider>()
.toggle(provider.pendingItems[i].id), .toggle(pending[i].id),
onRemove: () => context onRemove: () => context
.read<ShoppingListProvider>() .read<ShoppingListProvider>()
.remove(provider.pendingItems[i].id), .remove(pending[i].id),
), ),
], ],
], ],
@@ -150,13 +150,13 @@ class _ShoppingListPageState extends State<ShoppingListPage> {
), ),
// Checked section // Checked section
if (provider.checkedItems.isNotEmpty) ...[ if (checked.isNotEmpty) ...[
Padding( Padding(
padding: const EdgeInsets.symmetric(vertical: 12), padding: const EdgeInsets.symmetric(vertical: 12),
child: Row( child: Row(
children: [ children: [
Text( Text(
'COMPLETATI (${provider.checkedItems.length})', 'COMPLETATI (${checked.length})',
style: theme.textTheme.labelSmall?.copyWith( style: theme.textTheme.labelSmall?.copyWith(
fontWeight: FontWeight.w700, fontWeight: FontWeight.w700,
letterSpacing: 0.8, letterSpacing: 0.8,
@@ -178,20 +178,18 @@ class _ShoppingListPageState extends State<ShoppingListPage> {
margin: EdgeInsets.zero, margin: EdgeInsets.zero,
child: Column( child: Column(
children: [ children: [
for (int i = 0; for (int i = 0; i < checked.length; i++) ...[
i < provider.checkedItems.length;
i++) ...[
if (i > 0) if (i > 0)
const Divider( const Divider(
height: 1, indent: 16, endIndent: 16), height: 1, indent: 16, endIndent: 16),
ShoppingItemTile( ShoppingItemTile(
item: provider.checkedItems[i], item: checked[i],
onToggle: () => context onToggle: () => context
.read<ShoppingListProvider>() .read<ShoppingListProvider>()
.toggle(provider.checkedItems[i].id), .toggle(checked[i].id),
onRemove: () => context onRemove: () => context
.read<ShoppingListProvider>() .read<ShoppingListProvider>()
.remove(provider.checkedItems[i].id), .remove(checked[i].id),
), ),
], ],
], ],