perf(home): 四个根 tab 改为首次可见才构建

原先 IndexedStack 冷启动就把推荐/发现/追剧/我的四棵子树全建出来,各自还会发请求;
现在只建当前 tab,切过去再建并常驻,冷启动少三页构建和一次观看历史请求。
This commit is contained in:
Vicky authored and trae-solo-agent committed 2026-10-29 11:25:47 +08:00
1 parent 9f7301305e
commit 5649e4c3d4
2 files changed
+47 -15

No files matched your search

+45 -12
View File
@@ -161,24 +161,18 @@ class _HomeTabsState extends State<_HomeTabs> {
}
Widget _body(BuildContext context) {
final pages = <Widget>[
_recommend(context),
_recommendDiscover(context),
FollowingPage(
final builders = <WidgetBuilder>[
_recommend,
_recommendDiscover,
(context) => FollowingPage(
onGoHome: () => logic.select(0),
favoriteController: context.read<FavoriteController>(),
historyRequest: logic.followingHistoryRequest,
visible: logic.tab == 2,
),
_my(context),
_my,
];
return IndexedStack(
index: logic.tab,
children: [
for (var index = 0; index < pages.length; index++)
TickerMode(enabled: logic.tab == index, child: pages[index]),
],
);
return _LazyTabStack(index: logic.tab, builders: builders);
}
Widget _recommend(BuildContext context) {
@@ -248,3 +242,42 @@ class _HomeTabsState extends State<_HomeTabs> {
logic.select(tab);
}
}
/// 四个根 tab 的容器:只有被访问过的 tab 才真正构建并常驻。
///
/// 冷启动时只建推荐页,其余 tab 等第一次切过去再建,省掉三棵子树和它们各自的请求。
class _LazyTabStack extends StatefulWidget {
const _LazyTabStack({required this.index, required this.builders});
final int index;
final List<WidgetBuilder> builders;
@override
State<_LazyTabStack> createState() => _LazyTabStackState();
}
class _LazyTabStackState extends State<_LazyTabStack> {
late final Set<int> _visited = {widget.index};
@override
void didUpdateWidget(covariant _LazyTabStack oldWidget) {
super.didUpdateWidget(oldWidget);
_visited.add(widget.index);
}
@override
Widget build(BuildContext context) {
return IndexedStack(
index: widget.index,
children: [
for (var index = 0; index < widget.builders.length; index++)
TickerMode(
enabled: widget.index == index,
child: _visited.contains(index)
? widget.builders[index](context)
: const SizedBox.shrink(),
),
],
);
}
}