perf: ajout de ListView itemExtent/prototypeItem pour l'optimisation des performances

This commit is contained in:
ElPoyo
2026-05-26 13:43:18 +02:00
parent 0bbc77ffc8
commit 4284142b1e
2 changed files with 79 additions and 65 deletions
+74 -62
View File
@@ -601,80 +601,92 @@ class _CalendarPageState extends State<CalendarPage> {
constraints: BoxConstraints( constraints: BoxConstraints(
maxHeight: isMobile ? 240 : 280, maxHeight: isMobile ? 240 : 280,
), ),
child: ListView.separated( child: ListView.builder(
shrinkWrap: true, shrinkWrap: true,
itemCount: _searchResults.length, itemCount: _searchResults.length,
physics: const ClampingScrollPhysics(), physics: const ClampingScrollPhysics(),
separatorBuilder: (context, index) => // ✅ prototypeItem : les résultats ont une hauteur variable
const SizedBox(height: 8), // selon la présence du champ adresse (~56px sans, ~70px avec).
// prototypeItem à 72px (cas avec adresse + padding) pour
// que Flutter estime correctement la hauteur scrollable.
// ListView.separated ne supporte pas itemExtent/prototypeItem,
// d'où la conversion en ListView.builder avec séparateur intégré.
prototypeItem: const SizedBox(height: 72),
itemBuilder: (context, index) { itemBuilder: (context, index) {
final event = _searchResults[index]; final event = _searchResults[index];
final isSelected = _selectedEvent?.id == event.id; final isSelected = _selectedEvent?.id == event.id;
final isLast = index == _searchResults.length - 1;
return Material( return Column(
color: isSelected mainAxisSize: MainAxisSize.min,
? AppColors.rouge.withOpacity(0.08) children: [
: Colors.white, Material(
borderRadius: BorderRadius.circular(12), color: isSelected
child: InkWell( ? AppColors.rouge.withOpacity(0.08)
borderRadius: BorderRadius.circular(12), : Colors.white,
onTap: () => _onSearchResultSelected(event), borderRadius: BorderRadius.circular(12),
child: Padding( child: InkWell(
padding: const EdgeInsets.all(12), borderRadius: BorderRadius.circular(12),
child: Row( onTap: () => _onSearchResultSelected(event),
children: [ child: Padding(
Container( padding: const EdgeInsets.all(12),
width: 10, child: Row(
height: 10, children: [
decoration: BoxDecoration( Container(
color: _getStatusColor(event.status), width: 10,
shape: BoxShape.circle, height: 10,
), decoration: BoxDecoration(
), color: _getStatusColor(event.status),
const SizedBox(width: 12), shape: BoxShape.circle,
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
event.name,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: const TextStyle(
fontWeight: FontWeight.w600,
),
), ),
const SizedBox(height: 4), ),
Text( const SizedBox(width: 12),
_formatSearchResultDate( Expanded(
event.startDateTime), child: Column(
style: TextStyle( crossAxisAlignment: CrossAxisAlignment.start,
color: Colors.grey.shade700, children: [
fontSize: 12, Text(
), event.name,
), maxLines: 1,
if (event.address.isNotEmpty) ...[ overflow: TextOverflow.ellipsis,
const SizedBox(height: 2), style: const TextStyle(
Text( fontWeight: FontWeight.w600,
event.address, ),
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(
color: Colors.grey.shade600,
fontSize: 12,
), ),
), const SizedBox(height: 4),
], Text(
], _formatSearchResultDate(
), event.startDateTime),
style: TextStyle(
color: Colors.grey.shade700,
fontSize: 12,
),
),
if (event.address.isNotEmpty) ...[
const SizedBox(height: 2),
Text(
event.address,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(
color: Colors.grey.shade600,
fontSize: 12,
),
),
],
],
),
),
const SizedBox(width: 8),
const Icon(Icons.chevron_right,
color: Colors.grey),
],
), ),
const SizedBox(width: 8), ),
const Icon(Icons.chevron_right,
color: Colors.grey),
],
), ),
), ),
), if (!isLast) const SizedBox(height: 8),
],
); );
}, },
), ),
@@ -501,9 +501,11 @@ class _EquipmentManagementPageState extends State<EquipmentManagementPage>
return ListView.builder( return ListView.builder(
controller: _scrollController, controller: _scrollController,
itemCount: itemCount, itemCount: itemCount,
// ✅ Ajouter une estimation de la hauteur pour améliorer le scroll // ✅ prototypeItem utilisé car les cartes ont des hauteurs variables :
// Note : À ajuster selon la hauteur réelle de vos cartes // - Les équipements standards (ListTile + margin) font ~88px
// itemExtent: 140, // Décommentez si toutes les cartes ont la même hauteur // - Les consommables/câbles affichent _buildQuantityDisplay en plus (~30px)
// - prototypeItem permet à Flutter d'optimiser le scroll sans couper les items
prototypeItem: const SizedBox(height: 88),
// ✅ Augmenter le cache pour un scroll plus fluide // ✅ Augmenter le cache pour un scroll plus fluide
cacheExtent: 500, // Précharger 500px en plus cacheExtent: 500, // Précharger 500px en plus
itemBuilder: (context, index) { itemBuilder: (context, index) {