FOYDALI MAQOLALAR Flutter ilovalarini optimallashtirishning eng yaxshi usullari: Mutaxassis qo'llanmasi Bugun sizlar bilan real proyektlarda duch kelgan va hal qilgan eng muhim performance muammolarim haqida gaplashamiz
Bugun asosiy ko'radigan qismlar:
Network Calls
API responselarni cache qilish
Pagination implementatsiyasi
Offline-first arxitektura
Asset Management
SVG fayllarni vector grafikaga o'tkazish
Heavy assetlarni lazy load qilish
Kodlar bilan ko'rib chiqamiz
Copy // 1. API Caching va Offline-first arxitektura
class ApiService {
final Dio _dio = Dio();
final Box _cacheBox = Hive.box('api_cache');
Future<T> getData<T>({
required String endpoint,
required T Function(Map<String, dynamic>) fromJson,
Duration cacheDuration = const Duration(hours: 1),
}) async {
try {
// Cache dan ma'lumotni olish
final cachedData = _cacheBox.get(endpoint);
final cacheTime = _cacheBox.get('${endpoint}_time');
if (cachedData != null && cacheTime != null) {
final difference = DateTime.now().difference(DateTime.parse(cacheTime));
if (difference < cacheDuration) {
return fromJson(jsonDecode(cachedData));
}
}
// Agar cache da yo'q bo'lsa yoki eskirgan bo'lsa
final response = await _dio.get(endpoint);
// Cache ga saqlash
await _cacheBox.put(endpoint, jsonEncode(response.data));
await _cacheBox.put('${endpoint}_time', DateTime.now().toIso8601String());
return fromJson(response.data);
} catch (e) {
// Offline bo'lsa cache dan qaytarish
if (e is DioException && e.type == DioExceptionType.connectionError) {
final cachedData = _cacheBox.get(endpoint);
if (cachedData != null) {
return fromJson(jsonDecode(cachedData));
}
}
throw e;
}
}
}
API Caching va Offline-first :
ApiService
class HTTP so'rovlarni boshqaradi
Hive database yordamida ma'lumotlarni cache qiladi
Offline bo'lganda cache'dan ma'lumotlarni qaytaradi
Cache duration boshqarish imkoniyati
Copy // 2. Pagination implementation
class PaginatedListView extends StatefulWidget {
final Future<List<dynamic>> Function(int page) fetchData;
const PaginatedListView({required this.fetchData});
@override
_PaginatedListViewState createState() => _PaginatedListViewState();
}
class _PaginatedListViewState extends State<PaginatedListView> {
final List<dynamic> _items = [];
int _page = 1;
bool _isLoading = false;
bool _hasMore = true;
final _scrollController = ScrollController();
@override
void initState() {
super.initState();
_loadMore();
_scrollController.addListener(_onScroll);
}
Future<void> _loadMore() async {
if (_isLoading || !_hasMore) return;
setState(() => _isLoading = true);
try {
final newItems = await widget.fetchData(_page);
setState(() {
_items.addAll(newItems);
_page++;
_hasMore = newItems.isNotEmpty;
_isLoading = false;
});
} catch (e) {
setState(() => _isLoading = false);
}
}
void _onScroll() {
if (_scrollController.position.pixels >=
_scrollController.position.maxScrollExtent - 200) {
_loadMore();
}
}
@override
Widget build(BuildContext context) {
return ListView.builder(
controller: _scrollController,
itemCount: _items.length + (_hasMore ? 1 : 0),
itemBuilder: (context, index) {
if (index == _items.length) {
return const Center(child: CircularProgressIndicator());
}
return ListTile(title: Text(_items[index].toString()));
},
);
}
}
Pagination :
PaginatedListView
scroll paytida yangi ma'lumotlarni yuklaydi
Scroll position tekshiradi va kerak bo'lganda yangi page yuklaydi
Loading holatini ko'rsatadi
Memory optimization uchun ma'lumotlarni page bo'yicha yuklaydi
Copy // 3. Image precaching va lazy loading
class OptimizedImageView extends StatelessWidget {
final String imageUrl;
const OptimizedImageView({required this.imageUrl});
@override
Widget build(BuildContext context) {
return CachedNetworkImage(
imageUrl: imageUrl,
placeholder: (context, url) => const ShimmerPlaceholder(),
errorWidget: (context, url, error) => const Icon(Icons.error),
// Katta rasmlarni memory cache ga saqlash
memCacheHeight: 1080,
memCacheWidth: 1920,
// Disk cache duration
cacheManager: CacheManager(
Config(
'images_key',
stalePeriod: const Duration(days: 7),
maxNrOfCacheObjects: 100,
),
),
);
}
}
// Placeholder widget
class ShimmerPlaceholder extends StatelessWidget {
const ShimmerPlaceholder();
@override
Widget build(BuildContext context) {
return Shimmer.fromColors(
baseColor: Colors.grey[300]!,
highlightColor: Colors.grey[100]!,
child: Container(
width: double.infinity,
height: 200,
color: Colors.white,
),
);
}
}
Image Optimization :
CachedNetworkImage
orqali rasmlarni cache qilish
Memory va disk cache sozlamalari
Placeholder va error widget'lar
Rasm o'lchamlarini optimize qilish
Copy // 4. SVG optimization
class OptimizedSvgView extends StatelessWidget {
final String svgPath;
const OptimizedSvgView({required this.svgPath});
@override
Widget build(BuildContext context) {
// SVG ni vector grafikaga o'tkazish
return SvgPicture.asset(
svgPath,
placeholderBuilder: (context) => const ShimmerPlaceholder(),
// Render optimization
cacheColorFilter: true,
);
}
}
// Placeholder widget
class ShimmerPlaceholder extends StatelessWidget {
const ShimmerPlaceholder();
@override
Widget build(BuildContext context) {
return Shimmer.fromColors(
baseColor: Colors.grey[300]!,
highlightColor: Colors.grey[100]!,
child: Container(
width: double.infinity,
height: 200,
color: Colors.white,
),
);
}
}
SVG Optimization :
SVG fayllarni vector grafikaga o'tkazish
Cache colorFilter yoqish orqali rendering tezlashtirish
Copy // 5. Heavy asset lazy loading
class LazyLoadedView extends StatefulWidget {
@override
_LazyLoadedViewState createState() => _LazyLoadedViewState();
}
class _LazyLoadedViewState extends State<LazyLoadedView> {
late Future<void> _precacheTask;
@override
void initState() {
super.initState();
_precacheTask = _precacheAssets();
}
Future<void> _precacheAssets() async {
// Heavy assetlarni prioritet bo'yicha yuklash
await Future.wait([
precacheImage(const AssetImage('assets/high_priority.jpg'), context),
_loadSvgFromAsset('assets/icons/main_icon.svg'),
]);
// Secondary assetlarni keyin yuklash
unawaited(Future.wait([
precacheImage(const AssetImage('assets/secondary.jpg'), context),
_loadSvgFromAsset('assets/icons/secondary_icon.svg'),
]));
}
Future<void> _loadSvgFromAsset(String assetPath) async {
final loader = SvgAssetLoader(assetPath);
await svg.cache.putIfAbsent(assetPath, () => loader.load());
}
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: _precacheTask,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const ShimmerPlaceholder();
}
return SingleChildScrollView(
child: Column(
children: [
Image.asset('assets/high_priority.jpg'),
SvgPicture.asset('assets/icons/main_icon.svg'),
// Secondary assetlar
const OptimizedImageView(imageUrl: 'assets/secondary.jpg'),
const OptimizedSvgView(svgPath: 'assets/icons/secondary_icon.svg'),
],
),
);
},
);
}
}
// Placeholder widget
class ShimmerPlaceholder extends StatelessWidget {
const ShimmerPlaceholder();
@override
Widget build(BuildContext context) {
return Shimmer.fromColors(
baseColor: Colors.grey[300]!,
highlightColor: Colors.grey[100]!,
child: Container(
width: double.infinity,
height: 200,
color: Colors.white,
),
);
}
}
Heavy Asset Lazy Loading :
Assetlarni prioritet bo'yicha yuklash
High priority assetlar birinchi yuklanadi
Secondary assetlar background'da yuklanadi
Loading paytida shimmer effect ko'rsatish
Xulosa
Bu optimizatsiyalar orqali:
Batareya quvvati yaxshilanadi
Memory ya'ni xotira kam ishlatiladi
Dasturni oflayn ishlash imkoniyati qo'shiladi
User experience ya'ni foydalanuvchining dasturdagi taasuroti yaxshilanadi
Last updated 4 months ago