Refactoring

This commit is contained in:
DahoudG
2025-09-17 17:54:06 +00:00
parent 12d514d866
commit 63fe107f98
165 changed files with 54220 additions and 276 deletions

View File

@@ -0,0 +1,366 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import '../../../../core/performance/performance_optimizer.dart';
import '../../../../core/performance/smart_cache_service.dart';
import '../../../../shared/widgets/performance/optimized_list_view.dart';
import '../../../../shared/theme/app_theme.dart';
/// Page de démonstration des optimisations de performance
class PerformanceDemoPage extends StatefulWidget {
const PerformanceDemoPage({super.key});
@override
State<PerformanceDemoPage> createState() => _PerformanceDemoPageState();
}
class _PerformanceDemoPageState extends State<PerformanceDemoPage>
with TickerProviderStateMixin {
final _optimizer = PerformanceOptimizer();
final _cacheService = SmartCacheService();
// Données de test pour les démonstrations
List<DemoItem> _items = [];
bool _isLoading = false;
bool _hasMore = true;
// Contrôleurs d'animation
late AnimationController _fadeController;
late AnimationController _slideController;
@override
void initState() {
super.initState();
// Initialiser le service de cache
_cacheService.initialize();
// Initialiser les contrôleurs d'animation optimisés
_fadeController = PerformanceOptimizer.createOptimizedController(
duration: const Duration(milliseconds: 500),
vsync: this,
debugLabel: 'FadeController',
);
_slideController = PerformanceOptimizer.createOptimizedController(
duration: const Duration(milliseconds: 300),
vsync: this,
debugLabel: 'SlideController',
);
// Démarrer le monitoring des performances
_optimizer.startPerformanceMonitoring();
// Générer des données initiales
_generateInitialData();
// Démarrer les animations
_fadeController.forward();
_slideController.forward();
}
@override
void dispose() {
PerformanceOptimizer.disposeControllers([_fadeController, _slideController]);
super.dispose();
}
void _generateInitialData() {
_items = List.generate(20, (index) => DemoItem(
id: index,
title: 'Élément $index',
subtitle: 'Description de l\'élément $index',
value: (index * 10).toDouble(),
));
}
Future<void> _loadMoreItems() async {
if (_isLoading || !_hasMore) return;
setState(() {
_isLoading = true;
});
_optimizer.startTimer('load_more_items');
// Simuler un délai de chargement
await Future.delayed(const Duration(milliseconds: 800));
final newItems = List.generate(10, (index) => DemoItem(
id: _items.length + index,
title: 'Élément ${_items.length + index}',
subtitle: 'Description de l\'élément ${_items.length + index}',
value: ((_items.length + index) * 10).toDouble(),
));
setState(() {
_items.addAll(newItems);
_isLoading = false;
_hasMore = _items.length < 100; // Limiter à 100 éléments
});
_optimizer.stopTimer('load_more_items');
}
Future<void> _refreshItems() async {
_optimizer.startTimer('refresh_items');
// Simuler un délai de rafraîchissement
await Future.delayed(const Duration(milliseconds: 500));
setState(() {
_generateInitialData();
_hasMore = true;
});
_optimizer.stopTimer('refresh_items');
}
void _testCachePerformance() async {
_optimizer.startTimer('cache_test');
// Test d'écriture en cache
for (int i = 0; i < 100; i++) {
await _cacheService.put('test_key_$i', 'test_value_$i');
}
// Test de lecture en cache
for (int i = 0; i < 100; i++) {
await _cacheService.get<String>('test_key_$i');
}
_optimizer.stopTimer('cache_test');
final cacheInfo = await _cacheService.getCacheInfo();
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Test de cache terminé: $cacheInfo'),
backgroundColor: AppTheme.successColor,
),
);
}
}
void _showPerformanceStats() {
final stats = _optimizer.getPerformanceStats();
final cacheStats = _cacheService.getStats();
showDialog(
context: context,
builder: (context) => AlertDialog(
title: const Text('Statistiques de Performance'),
content: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
const Text('Optimiseur:', style: TextStyle(fontWeight: FontWeight.bold)),
...stats.entries.map((e) => Text('${e.key}: ${e.value}')),
const SizedBox(height: 16),
const Text('Cache:', style: TextStyle(fontWeight: FontWeight.bold)),
Text(cacheStats.toString()),
],
),
),
actions: [
TextButton(
onPressed: () {
_optimizer.resetStats();
Navigator.of(context).pop();
},
child: const Text('Réinitialiser'),
),
TextButton(
onPressed: () => Navigator.of(context).pop(),
child: const Text('Fermer'),
),
],
),
);
}
void _clearAllCaches() {
_optimizer.clearAllCaches();
_cacheService.clear();
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Tous les caches ont été vidés'),
backgroundColor: AppTheme.warningColor,
),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Démonstration Performance'),
backgroundColor: AppTheme.primaryColor,
foregroundColor: Colors.white,
actions: [
IconButton(
icon: const Icon(Icons.analytics),
onPressed: _showPerformanceStats,
tooltip: 'Statistiques',
),
IconButton(
icon: const Icon(Icons.clear_all),
onPressed: _clearAllCaches,
tooltip: 'Vider les caches',
),
],
),
body: FadeTransition(
opacity: _fadeController,
child: Column(
children: [
// Section des boutons de test
Container(
padding: const EdgeInsets.all(16),
child: Wrap(
spacing: 8,
runSpacing: 8,
children: [
ElevatedButton.icon(
onPressed: _testCachePerformance,
icon: const Icon(Icons.speed),
label: const Text('Test Cache'),
style: ElevatedButton.styleFrom(
backgroundColor: AppTheme.primaryColor,
foregroundColor: Colors.white,
),
),
ElevatedButton.icon(
onPressed: () {
HapticFeedback.lightImpact();
PerformanceOptimizer.forceGarbageCollection();
},
icon: const Icon(Icons.cleaning_services),
label: const Text('Force GC'),
style: ElevatedButton.styleFrom(
backgroundColor: AppTheme.warningColor,
foregroundColor: Colors.white,
),
),
ElevatedButton.icon(
onPressed: _showPerformanceStats,
icon: const Icon(Icons.bar_chart),
label: const Text('Stats'),
style: ElevatedButton.styleFrom(
backgroundColor: AppTheme.infoColor,
foregroundColor: Colors.white,
),
),
],
),
),
// Liste optimisée
Expanded(
child: SlideTransition(
position: Tween<Offset>(
begin: const Offset(0, 0.1),
end: Offset.zero,
).animate(CurvedAnimation(
parent: _slideController,
curve: Curves.easeOutCubic,
)),
child: OptimizedListView<DemoItem>(
items: _items,
itemBuilder: (context, item, index) => _buildDemoItem(item, index),
onLoadMore: _loadMoreItems,
onRefresh: _refreshItems,
hasMore: _hasMore,
isLoading: _isLoading,
loadMoreThreshold: 5,
itemExtent: 80,
enableAnimations: true,
enableRecycling: true,
maxCachedWidgets: 30,
emptyWidget: const Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.speed, size: 64, color: Colors.grey),
SizedBox(height: 16),
Text('Aucun élément de test', style: TextStyle(color: Colors.grey)),
],
),
),
),
),
),
],
),
),
);
}
Widget _buildDemoItem(DemoItem item, int index) {
return PerformanceOptimizer.optimizeWidget(
Card(
margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 4),
child: ListTile(
leading: CircleAvatar(
backgroundColor: AppTheme.primaryColor,
child: Text('${item.id}', style: const TextStyle(color: Colors.white)),
),
title: Text(item.title),
subtitle: Text(item.subtitle),
trailing: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'${item.value.toInt()}',
style: const TextStyle(
fontWeight: FontWeight.bold,
color: AppTheme.primaryColor,
),
),
const Text('pts', style: TextStyle(fontSize: 12)),
],
),
onTap: () {
HapticFeedback.selectionClick();
_optimizer.incrementCounter('item_tapped');
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Élément ${item.title} sélectionné'),
duration: const Duration(milliseconds: 800),
),
);
},
),
),
key: 'demo_item_${item.id}',
forceRepaintBoundary: true,
);
}
}
/// Modèle de données pour la démonstration
class DemoItem {
final int id;
final String title;
final String subtitle;
final double value;
DemoItem({
required this.id,
required this.title,
required this.subtitle,
required this.value,
});
@override
int get hashCode => id.hashCode;
@override
bool operator ==(Object other) {
return other is DemoItem && other.id == id;
}
}