perf: fix Android lag, snapping animations & slow image loading
Fix 1: Replace overshooting Cubic(1.95) tab glider curve with Curves.easeInOutCubic; reduce duration 450ms → 280ms Fix 2: Replace marquee jumpTo() with animateTo(linear) for fluid scroll Fix 3: Replace Image.network with CachedNetworkImage in search results Fix 4: Replace Image.network with CachedNetworkImage in desktop cards Fix 5: Wrap IndexedStack children in RepaintBoundary to isolate repaints across tabs (Home/Calendar/Contribute/Profile) Fix 6: Replace setState on PageView.onPageChanged with ValueNotifier so only the carousel dots widget rebuilds on swipe Fix 7: Wrap animated tab glider in RepaintBoundary Fix 8: Replace shrinkWrap:true ListView with ConstrainedBox(maxHeight) to eliminate O(n) layout pass in search results Fix 9: Increase image cache to 200MB / 500 images in main()
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
@@ -248,12 +249,16 @@ class _HomeDesktopScreenState extends State<HomeDesktopScreen> with SingleTicker
|
||||
|
||||
double next = cur + delta;
|
||||
if (next >= max) {
|
||||
// wrap back by half (seamless loop)
|
||||
// wrap back by half (seamless loop — instant jump is intentional)
|
||||
final wrapped = next - half;
|
||||
_marqueeController.jumpTo(wrapped.clamp(0.0, max));
|
||||
} else {
|
||||
// small incremental jump gives smooth appearance
|
||||
_marqueeController.jumpTo(next);
|
||||
// smooth incremental scroll synced to ticker duration
|
||||
_marqueeController.animateTo(
|
||||
next,
|
||||
duration: _marqueeTick,
|
||||
curve: Curves.linear,
|
||||
);
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -769,7 +774,16 @@ class _HomeDesktopScreenState extends State<HomeDesktopScreen> with SingleTicker
|
||||
child: Row(children: [
|
||||
ClipRRect(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
child: img != null ? Image.network(img, width: 64, height: 64, fit: BoxFit.cover) : Container(width: 64, height: 64, color: Theme.of(context).dividerColor),
|
||||
child: img != null
|
||||
? CachedNetworkImage(
|
||||
imageUrl: img,
|
||||
width: 64,
|
||||
height: 64,
|
||||
fit: BoxFit.cover,
|
||||
placeholder: (_, __) => Container(width: 64, height: 64, color: Theme.of(context).dividerColor),
|
||||
errorWidget: (_, __, ___) => Container(width: 64, height: 64, color: Theme.of(context).dividerColor, child: const Icon(Icons.event, size: 24, color: Colors.grey)),
|
||||
)
|
||||
: Container(width: 64, height: 64, color: Theme.of(context).dividerColor),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
Expanded(
|
||||
@@ -817,7 +831,14 @@ class _HomeDesktopScreenState extends State<HomeDesktopScreen> with SingleTicker
|
||||
ClipRRect(
|
||||
borderRadius: const BorderRadius.vertical(top: Radius.circular(cardRadius)),
|
||||
child: img != null
|
||||
? Image.network(img, width: double.infinity, height: imageHeight, fit: BoxFit.cover, errorBuilder: (_, __, ___) => Container(height: imageHeight, color: theme.dividerColor))
|
||||
? CachedNetworkImage(
|
||||
imageUrl: img,
|
||||
width: double.infinity,
|
||||
height: imageHeight,
|
||||
fit: BoxFit.cover,
|
||||
placeholder: (_, __) => Container(height: imageHeight, color: theme.dividerColor),
|
||||
errorWidget: (_, __, ___) => Container(height: imageHeight, color: theme.dividerColor),
|
||||
)
|
||||
: Container(height: imageHeight, width: double.infinity, color: theme.dividerColor),
|
||||
),
|
||||
|
||||
@@ -921,7 +942,14 @@ class _HomeDesktopScreenState extends State<HomeDesktopScreen> with SingleTicker
|
||||
ClipRRect(
|
||||
borderRadius: const BorderRadius.vertical(top: Radius.circular(cardRadius)),
|
||||
child: img != null
|
||||
? Image.network(img, width: width, height: imageHeight, fit: BoxFit.cover, errorBuilder: (_, __, ___) => Container(height: imageHeight, color: theme.dividerColor))
|
||||
? CachedNetworkImage(
|
||||
imageUrl: img,
|
||||
width: width,
|
||||
height: imageHeight,
|
||||
fit: BoxFit.cover,
|
||||
placeholder: (_, __) => Container(height: imageHeight, color: theme.dividerColor),
|
||||
errorWidget: (_, __, ___) => Container(height: imageHeight, color: theme.dividerColor),
|
||||
)
|
||||
: Container(height: imageHeight, width: width, color: theme.dividerColor),
|
||||
),
|
||||
|
||||
|
||||
Reference in New Issue
Block a user