From 35429c132ce5e14bf24ab5ac32a67a59a9140036 Mon Sep 17 00:00:00 2001 From: nyne Date: Fri, 7 Feb 2025 18:15:36 +0800 Subject: [PATCH] Improve comic page performance --- lib/components/layout.dart | 15 ++++++ lib/pages/comic_page.dart | 102 +++++++++++++++++++------------------ 2 files changed, 67 insertions(+), 50 deletions(-) diff --git a/lib/components/layout.dart b/lib/components/layout.dart index 51351c2..0238863 100644 --- a/lib/components/layout.dart +++ b/lib/components/layout.dart @@ -148,3 +148,18 @@ class SliverGridDelegateWithComics extends SliverGridDelegate { return false; } } + +class SliverLazyToBoxAdapter extends StatelessWidget { + /// Creates a sliver that contains a single box widget which can be lazy loaded. + const SliverLazyToBoxAdapter({super.key, required this.child}); + + final Widget child; + + @override + Widget build(BuildContext context) { + return SliverList.list(children: [ + SizedBox(), + child, + ]); + } +} diff --git a/lib/pages/comic_page.dart b/lib/pages/comic_page.dart index 716ca05..6bf09da 100644 --- a/lib/pages/comic_page.dart +++ b/lib/pages/comic_page.dart @@ -206,62 +206,64 @@ class _ComicPageState extends LoadingState yield const SliverPadding(padding: EdgeInsets.only(top: 8)); - yield Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const SizedBox(width: 16), - Hero( - tag: "cover${comic.id}${comic.sourceKey}", - child: Container( - decoration: BoxDecoration( - color: context.colorScheme.primaryContainer, - borderRadius: BorderRadius.circular(8), - boxShadow: [ - BoxShadow( - color: context.colorScheme.outlineVariant, - blurRadius: 1, - offset: const Offset(0, 1), + yield SliverLazyToBoxAdapter( + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const SizedBox(width: 16), + Hero( + tag: "cover${comic.id}${comic.sourceKey}", + child: Container( + decoration: BoxDecoration( + color: context.colorScheme.primaryContainer, + borderRadius: BorderRadius.circular(8), + boxShadow: [ + BoxShadow( + color: context.colorScheme.outlineVariant, + blurRadius: 1, + offset: const Offset(0, 1), + ), + ], + ), + height: 144, + width: 144 * 0.72, + clipBehavior: Clip.antiAlias, + child: AnimatedImage( + image: CachedImageProvider( + widget.cover ?? comic.cover, + sourceKey: comic.sourceKey, + cid: comic.id, + ), + width: double.infinity, + height: double.infinity, + ), + ), + ), + const SizedBox(width: 16), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SelectableText(comic.title, style: ts.s18), + if (comic.subTitle != null) + SelectableText(comic.subTitle!, style: ts.s14) + .paddingVertical(4), + Text( + (ComicSource.find(comic.sourceKey)?.name) ?? '', + style: ts.s12, ), ], ), - height: 144, - width: 144 * 0.72, - clipBehavior: Clip.antiAlias, - child: AnimatedImage( - image: CachedImageProvider( - widget.cover ?? comic.cover, - sourceKey: comic.sourceKey, - cid: comic.id, - ), - width: double.infinity, - height: double.infinity, - ), ), - ), - const SizedBox(width: 16), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SelectableText(comic.title, style: ts.s18), - if (comic.subTitle != null) - SelectableText(comic.subTitle!, style: ts.s14) - .paddingVertical(4), - Text( - (ComicSource.find(comic.sourceKey)?.name) ?? '', - style: ts.s12, - ), - ], - ), - ), - ], - ).toSliver(); + ], + ), + ); } Widget buildActions() { bool isMobile = context.width < changePoint; bool hasHistory = history != null && (history!.ep > 1 || history!.page > 1); - return SliverToBoxAdapter( + return SliverLazyToBoxAdapter( child: Column( children: [ ListView( @@ -354,7 +356,7 @@ class _ComicPageState extends LoadingState if (comic.description == null || comic.description!.trim().isEmpty) { return const SliverPadding(padding: EdgeInsets.zero); } - return SliverToBoxAdapter( + return SliverLazyToBoxAdapter( child: Column( children: [ ListTile( @@ -482,7 +484,7 @@ class _ComicPageState extends LoadingState bool enableTranslation = App.locale.languageCode == 'zh' && comicSource.enableTagsTranslate; - return SliverToBoxAdapter( + return SliverLazyToBoxAdapter( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -1875,7 +1877,7 @@ class _CommentsPartState extends State<_CommentsPart> { Widget build(BuildContext context) { return MultiSliver( children: [ - SliverToBoxAdapter( + SliverLazyToBoxAdapter( child: ListTile( title: Text("Comments".tl), trailing: Row(