admin管理员组文章数量:1023803
I have a page with a ListView
, each tile contains an image and text. The tiles are generated from a list of objects. Each object has properties text
and imageId
. imageId
is used to retrieve the image from the "images" table in the local database. The "images" table has columns id
(TEXT) and picture
(BLOB). I am using SQLite with sqflite (mobile) and sqflite_common_ffi (desktop).
List<Request> _requests = [];
List<ImagesItem> _images = [];
bool _isLoading = true;
@override
void initState() {
super.initState();
loadRequests();
}
void loadRequests() async {
try {
var requests = await RequestsRepository().getAllRequests();
requests = requests.take(1).toList(); // take(1) for testing purposes
var alreadyStoredImages = _images.map((image) => image.id).toSet();
var images = await ImageRepository().getImagesByIds(
requests
.map((request) => request.imageId)
.where((imageId) => !alreadyStoredImages.contains(imageId))
.toList(),
);
setState(() {
_images = images;
_requests = requests;
});
} catch (error) {
// Handle error
} finally {
setState(() {
_isLoading = false;
});
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: _isLoading
? const Center(child: CircularProgressIndicator())
: ListView.builder(
itemCount: _requests.length,
itemBuilder: (context, index) {
final request = _requests[index];
final image = _images.firstWhere(
(img) => img.id == request.imageId,
);
return ListTile(
leading: Image.memory(
image.picture,
width: 50,
height: 50,
),
);
},
),
);
}
The text appears instantly but the images take about 2 seconds to load. Is it normal for images to take this long to load from a local database? I could show a loader before showing the ListView but I don't know how to let the Image Widget load the image and after that show everything.
In another attempt with PrecacheImage
the images are MemoryImage
instead of Uint8List
. The Image widget uses MemoryImage
instead of Image.memory()
. The page loads almost instantly. The code changed with precacheImage
:
class _RequestWithImagePreCache {
final String id;
final MemoryImage image;
_RequestWithImagePreCache(this.id, this.image);
}
List<_RequestWithImagePreCache> _images = [];
void loadRequests() async {
try {
var requests = await RequestsRepository().getAllRequests();
requests = requests.take(1).toList(); // take(1) for testing purposes
var alreadyStoredImages = _images.map((image) => image.id).toSet();
var images = await ImageRepository().getImagesByIds(
requests
.map((request) => request.imageId)
.where((imageId) => !alreadyStoredImages.contains(imageId))
.toList(),
);
List<_RequestWithImagePreCache> imagesCached = [];
await Future.wait(images.map((image) async {
final memoryImage = MemoryImage(image.picture);
await precacheImage(memoryImage, context);
imagesCached.add(_RequestWithImagePreCache(image.id, memoryImage));
}));
setState(() {
_images = imagesCached;
_requests = requests;
});
} catch (error) {
// Handle any errors during data fetching
} finally {
setState(() {
_isLoading = false;
});
}
}
The use of precacheImage
is not clear to me as all guides use it in the context of images retrieved from the web, or use the package cached_network_image which I believe uses precacheImage
or something similar. Is there a behavior to follow and why does the second case load faster even if I have to push images to cache instead of directly using them after retrieving from database?
I have a page with a ListView
, each tile contains an image and text. The tiles are generated from a list of objects. Each object has properties text
and imageId
. imageId
is used to retrieve the image from the "images" table in the local database. The "images" table has columns id
(TEXT) and picture
(BLOB). I am using SQLite with sqflite (mobile) and sqflite_common_ffi (desktop).
List<Request> _requests = [];
List<ImagesItem> _images = [];
bool _isLoading = true;
@override
void initState() {
super.initState();
loadRequests();
}
void loadRequests() async {
try {
var requests = await RequestsRepository().getAllRequests();
requests = requests.take(1).toList(); // take(1) for testing purposes
var alreadyStoredImages = _images.map((image) => image.id).toSet();
var images = await ImageRepository().getImagesByIds(
requests
.map((request) => request.imageId)
.where((imageId) => !alreadyStoredImages.contains(imageId))
.toList(),
);
setState(() {
_images = images;
_requests = requests;
});
} catch (error) {
// Handle error
} finally {
setState(() {
_isLoading = false;
});
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: _isLoading
? const Center(child: CircularProgressIndicator())
: ListView.builder(
itemCount: _requests.length,
itemBuilder: (context, index) {
final request = _requests[index];
final image = _images.firstWhere(
(img) => img.id == request.imageId,
);
return ListTile(
leading: Image.memory(
image.picture,
width: 50,
height: 50,
),
);
},
),
);
}
The text appears instantly but the images take about 2 seconds to load. Is it normal for images to take this long to load from a local database? I could show a loader before showing the ListView but I don't know how to let the Image Widget load the image and after that show everything.
In another attempt with PrecacheImage
the images are MemoryImage
instead of Uint8List
. The Image widget uses MemoryImage
instead of Image.memory()
. The page loads almost instantly. The code changed with precacheImage
:
class _RequestWithImagePreCache {
final String id;
final MemoryImage image;
_RequestWithImagePreCache(this.id, this.image);
}
List<_RequestWithImagePreCache> _images = [];
void loadRequests() async {
try {
var requests = await RequestsRepository().getAllRequests();
requests = requests.take(1).toList(); // take(1) for testing purposes
var alreadyStoredImages = _images.map((image) => image.id).toSet();
var images = await ImageRepository().getImagesByIds(
requests
.map((request) => request.imageId)
.where((imageId) => !alreadyStoredImages.contains(imageId))
.toList(),
);
List<_RequestWithImagePreCache> imagesCached = [];
await Future.wait(images.map((image) async {
final memoryImage = MemoryImage(image.picture);
await precacheImage(memoryImage, context);
imagesCached.add(_RequestWithImagePreCache(image.id, memoryImage));
}));
setState(() {
_images = imagesCached;
_requests = requests;
});
} catch (error) {
// Handle any errors during data fetching
} finally {
setState(() {
_isLoading = false;
});
}
}
The use of precacheImage
is not clear to me as all guides use it in the context of images retrieved from the web, or use the package cached_network_image which I believe uses precacheImage
or something similar. Is there a behavior to follow and why does the second case load faster even if I have to push images to cache instead of directly using them after retrieving from database?
1 Answer
Reset to default 0as I read precacheImage
concept is like Cache image in CacheManager in theory it should slow on load image first time and store it in cache when reused the same image it will used cache instead of make a new one instant
I have a page with a ListView
, each tile contains an image and text. The tiles are generated from a list of objects. Each object has properties text
and imageId
. imageId
is used to retrieve the image from the "images" table in the local database. The "images" table has columns id
(TEXT) and picture
(BLOB). I am using SQLite with sqflite (mobile) and sqflite_common_ffi (desktop).
List<Request> _requests = [];
List<ImagesItem> _images = [];
bool _isLoading = true;
@override
void initState() {
super.initState();
loadRequests();
}
void loadRequests() async {
try {
var requests = await RequestsRepository().getAllRequests();
requests = requests.take(1).toList(); // take(1) for testing purposes
var alreadyStoredImages = _images.map((image) => image.id).toSet();
var images = await ImageRepository().getImagesByIds(
requests
.map((request) => request.imageId)
.where((imageId) => !alreadyStoredImages.contains(imageId))
.toList(),
);
setState(() {
_images = images;
_requests = requests;
});
} catch (error) {
// Handle error
} finally {
setState(() {
_isLoading = false;
});
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: _isLoading
? const Center(child: CircularProgressIndicator())
: ListView.builder(
itemCount: _requests.length,
itemBuilder: (context, index) {
final request = _requests[index];
final image = _images.firstWhere(
(img) => img.id == request.imageId,
);
return ListTile(
leading: Image.memory(
image.picture,
width: 50,
height: 50,
),
);
},
),
);
}
The text appears instantly but the images take about 2 seconds to load. Is it normal for images to take this long to load from a local database? I could show a loader before showing the ListView but I don't know how to let the Image Widget load the image and after that show everything.
In another attempt with PrecacheImage
the images are MemoryImage
instead of Uint8List
. The Image widget uses MemoryImage
instead of Image.memory()
. The page loads almost instantly. The code changed with precacheImage
:
class _RequestWithImagePreCache {
final String id;
final MemoryImage image;
_RequestWithImagePreCache(this.id, this.image);
}
List<_RequestWithImagePreCache> _images = [];
void loadRequests() async {
try {
var requests = await RequestsRepository().getAllRequests();
requests = requests.take(1).toList(); // take(1) for testing purposes
var alreadyStoredImages = _images.map((image) => image.id).toSet();
var images = await ImageRepository().getImagesByIds(
requests
.map((request) => request.imageId)
.where((imageId) => !alreadyStoredImages.contains(imageId))
.toList(),
);
List<_RequestWithImagePreCache> imagesCached = [];
await Future.wait(images.map((image) async {
final memoryImage = MemoryImage(image.picture);
await precacheImage(memoryImage, context);
imagesCached.add(_RequestWithImagePreCache(image.id, memoryImage));
}));
setState(() {
_images = imagesCached;
_requests = requests;
});
} catch (error) {
// Handle any errors during data fetching
} finally {
setState(() {
_isLoading = false;
});
}
}
The use of precacheImage
is not clear to me as all guides use it in the context of images retrieved from the web, or use the package cached_network_image which I believe uses precacheImage
or something similar. Is there a behavior to follow and why does the second case load faster even if I have to push images to cache instead of directly using them after retrieving from database?
I have a page with a ListView
, each tile contains an image and text. The tiles are generated from a list of objects. Each object has properties text
and imageId
. imageId
is used to retrieve the image from the "images" table in the local database. The "images" table has columns id
(TEXT) and picture
(BLOB). I am using SQLite with sqflite (mobile) and sqflite_common_ffi (desktop).
List<Request> _requests = [];
List<ImagesItem> _images = [];
bool _isLoading = true;
@override
void initState() {
super.initState();
loadRequests();
}
void loadRequests() async {
try {
var requests = await RequestsRepository().getAllRequests();
requests = requests.take(1).toList(); // take(1) for testing purposes
var alreadyStoredImages = _images.map((image) => image.id).toSet();
var images = await ImageRepository().getImagesByIds(
requests
.map((request) => request.imageId)
.where((imageId) => !alreadyStoredImages.contains(imageId))
.toList(),
);
setState(() {
_images = images;
_requests = requests;
});
} catch (error) {
// Handle error
} finally {
setState(() {
_isLoading = false;
});
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: _isLoading
? const Center(child: CircularProgressIndicator())
: ListView.builder(
itemCount: _requests.length,
itemBuilder: (context, index) {
final request = _requests[index];
final image = _images.firstWhere(
(img) => img.id == request.imageId,
);
return ListTile(
leading: Image.memory(
image.picture,
width: 50,
height: 50,
),
);
},
),
);
}
The text appears instantly but the images take about 2 seconds to load. Is it normal for images to take this long to load from a local database? I could show a loader before showing the ListView but I don't know how to let the Image Widget load the image and after that show everything.
In another attempt with PrecacheImage
the images are MemoryImage
instead of Uint8List
. The Image widget uses MemoryImage
instead of Image.memory()
. The page loads almost instantly. The code changed with precacheImage
:
class _RequestWithImagePreCache {
final String id;
final MemoryImage image;
_RequestWithImagePreCache(this.id, this.image);
}
List<_RequestWithImagePreCache> _images = [];
void loadRequests() async {
try {
var requests = await RequestsRepository().getAllRequests();
requests = requests.take(1).toList(); // take(1) for testing purposes
var alreadyStoredImages = _images.map((image) => image.id).toSet();
var images = await ImageRepository().getImagesByIds(
requests
.map((request) => request.imageId)
.where((imageId) => !alreadyStoredImages.contains(imageId))
.toList(),
);
List<_RequestWithImagePreCache> imagesCached = [];
await Future.wait(images.map((image) async {
final memoryImage = MemoryImage(image.picture);
await precacheImage(memoryImage, context);
imagesCached.add(_RequestWithImagePreCache(image.id, memoryImage));
}));
setState(() {
_images = imagesCached;
_requests = requests;
});
} catch (error) {
// Handle any errors during data fetching
} finally {
setState(() {
_isLoading = false;
});
}
}
The use of precacheImage
is not clear to me as all guides use it in the context of images retrieved from the web, or use the package cached_network_image which I believe uses precacheImage
or something similar. Is there a behavior to follow and why does the second case load faster even if I have to push images to cache instead of directly using them after retrieving from database?
1 Answer
Reset to default 0as I read precacheImage
concept is like Cache image in CacheManager in theory it should slow on load image first time and store it in cache when reused the same image it will used cache instead of make a new one instant
本文标签:
版权声明:本文标题:flutter - Why does pushing images to cache first load them faster than retrieving from database directly? - Stack Overflow 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://it.en369.cn/questions/1745575965a2157016.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论