Flutter New Gallery 弃用解析:弃用决策、仓库中的现状与性能基准测试角色
在 Flutter 官方仓库中,位于 dev/integration_tests/new_gallery 的 Flutter Gallery(包名 gallery)已于文档层面明确声明弃用(deprecated),不再接受主动维护。但它并未从代码库中移除——它如今的主要职责是作为性能基准(performance benchmark)与集成测试载体,被 devicelab 任务持续调用,用于跟踪页面过渡动画在不同平台、不同渲染后端(Skia / Impeller / OpenGLES / Vulkan)下的表现。读完本文,你能掌握 New Gallery 弃用后在仓库中的真实定位、其作为性能测试基准的完整调用链,以及官方文档推荐的替代学习资源。
一、官方声明:New Gallery 已弃用,仅保留测试用途
dev/integration_tests/new_gallery/README.md 以一条加粗 NOTE 开篇:
The Flutter Gallery is now deprecated, and no longer being active maintained.
文档随后给出了三点关键事实,这也是理解该项目现状的骨架:
- 历史定位:Flutter Gallery 曾经是一个帮助开发者评估和使用 Flutter 的展示型应用(a resource to help developers evaluate and use Flutter);
- 现状定位:现在主要被用于测试(now being used primarily for testing)——即作为引擎与框架的性能/行为基准;
- Web 归档:出于存档目的,其 Web 版本仍被保留在官方归档地址(文档中以外链形式提供,本文不重复输出外部链接)。
从仓库结构可以印证它的“测试”定位:它被放在 dev/integration_tests/ 目录下而非 examples/ 目录,且同时登记在仓库根 pubspec.yaml 的 pub workspace 成员列表中(第 44 行 - dev/integration_tests/new_gallery),与 flutter_gallery(旧版 Gallery)并列为 CI 测试工程的一部分。
二、弃用后的核心用途:性能基准测试
README 中“now being used primarily for testing”这一句,对应的就是 devicelab(Flutter 的设备实验室 CI 框架)里围绕 New Gallery 构建的一组性能测试任务。
2.1 基准测试入口:NewGalleryPerfTest
核心任务定义在 dev/devicelab/lib/tasks/new_gallery.dart:
class NewGalleryPerfTest extends PerfTest {
NewGalleryPerfTest({
String timelineFileName = 'transitions',
super.dartDefine = '',
super.enableImpeller,
super.timeoutSeconds,
super.forceOpenGLES,
}) : super(
'${flutterDirectory.path}/dev/integration_tests/new_gallery',
'test_driver/transitions_perf.dart',
timelineFileName,
createPlatforms: <String>['android', 'ios', 'web', 'macos', 'windows'],
enableMergedPlatformThread: true,
);
}
从这段源码可以读出几个实现事实:
- 被测工程:
dev/integration_tests/new_gallery; - 驱动入口:
test_driver/transitions_perf.dart,timeline 文件默认名为transitions(即跟踪的是页面“过渡”这一行为); - 覆盖平台:android、ios、web、macos、windows 五大平台;
- 可配置项:
dartDefine(用于切换只测某个 study)、enableImpeller(是否启用 Impeller 渲染器)、forceOpenGLES(强制 OpenGLES 后端)、timeoutSeconds。
2.2 围绕不同后端与平台的任务矩阵
dev/devicelab/bin/tasks/ 下存在一组以 new_gallery 前缀命名的任务脚本,构成完整的测试矩阵:
| 任务脚本 | 作用 |
|---|---|
| new_gallery__transition_perf.dart | Android 端标准过渡动画基准,超时设为 20 分钟以便失败时截取屏幕用于排障 |
| new_gallery__crane_perf.dart | 只测 Crane 这一个 study 的过渡动画 |
| new_gallery_ios__transition_perf.dart | iOS 平台过渡基准 |
| new_gallery_macos_impeller__transition_perf.dart | macOS + Impeller |
| new_gallery_impeller__transition_perf.dart | Impeller 渲染器基准 |
| new_gallery_impeller_old_zoom__transition_perf.dart | Impeller old_zoom 变体 |
| new_gallery_opengles_impeller__transition_perf.dart | Impeller + OpenGLES 后端 |
| new_gallery_skia_ios__transition_perf.dart | iOS + Skia(与 Impeller 对照组) |
| new_gallery_windows_impeller__transition_perf.dart、new_gallery_windows_skia__transition_perf.dart | Windows 双渲染器对照 |
| flutter_gallery_v2_chrome_run_test.dart、flutter_gallery_v2_web_compile_test.dart | Web 端运行与编译测试 |
任务名中的 v2 即指 New Gallery(第二代 Gallery)。docs/engine/impeller/docs/benchmarks.md 进一步说明:这些测试的帧光栅化时间(average / 90th / 99th / worst frame rasterizer time)会进入性能 dashboard,用于横向比较 Skia、Impeller Vulkan、Impeller OpenGLES 等渲染路径——这正是 README 所说“primarily for testing”的具体落点。
2.3 被测端:transitions_perf.dart 驱动协议
性能测试的被测端是 test_driver/transitions_perf.dart,其内容很短但信息量完整:
Future<String> _handleMessages(String? message) async {
switch (message) {
case 'demoDescriptions':
final List<String> demoDescriptions = Demos.allDescriptions();
return const JsonEncoder.withIndent(' ').convert(demoDescriptions);
case 'isTestingCraneOnly':
return const String.fromEnvironment('onlyCrane', defaultValue: 'false');
case 'isTestingReplyOnly':
return const String.fromEnvironment('onlyReply', defaultValue: 'false');
default:
throw 'unknown message';
}
}
void main() {
enableFlutterDriverExtension(handler: _handleMessages);
runApp(const GalleryApp(isTestMode: true));
}
它注册了 flutter_driver 扩展,并支持宿主侧查询三类信息:
demoDescriptions:返回全部 demo 的描述列表(来自 lib/data/demos.dart 中Demos.allDescriptions()),测试宿主据此驱动逐页过渡;isTestingCraneOnly/isTestingReplyOnly:通过dart-define的onlyCrane/onlyReply环境变量声明“本次只测某个 study”,对应上文 crane 专属基准任务。
文件顶部注释指向 transitions_perf_test.dart 作为宿主机侧的配套文件(位于 test_driver),整体构成 flutter_driver 的“宿主驱动 + 应用内扩展”标准架构。
三、工程本体:它仍然是一个完整可运行的演示应用
理解“为什么选它做基准”需要看一下工程本身的内容构成——一个覆盖 Flutter 主要 UI 范式的真实应用,恰好提供了丰富的页面过渡场景。
3.1 六大 Study 与三组 Demo
lib/data/demos.dart 中的 Demos.studies() 登记了六个完整 study 应用:
- Shrine(电商示例)、Rally(金融应用)、Crane(动画密集的目的地应用)、Fortnightly(新闻聚合)、Reply(邮件客户端)、Starter(入门模板);
- 对应的实现分别位于
lib/studies/shrine、lib/studies/rally、lib/studies/crane、lib/studies/fortnightly、lib/studies/reply、lib/studies/starter,各自带独立的app.dart与routes.dart。
同一文件还按 GalleryDemoCategory 枚举(study / material / cupertino / other)组织了三大类 widget 演示:
- Material demos(
lib/demos/material/):AppBar、Banner、BottomNavigationBar、BottomSheet、Button 五形态、Card、Chip 四形态、DataTable、Dialog 四形态、Drawer、NavigationRail、Date/Time/Range Picker、ProgressIndicator、Selection Controls、Slider、SnackBar、Tabs、TextField、Tooltip 等; - Cupertino demos(
lib/demos/cupertino/):ActivityIndicator、Alert/ActionSheet、Button、ContextMenu、NavigationBar、DatePicker、Scrollbar、SegmentedControl、Slider、Switch、TabBar、TextField 等; - Reference demos(
lib/demos/reference/):Colors、Typography、Transformations,以及五个RouteTransition变体(fade_scale、fade_through、shared_x_axis、shared_y_axis、shared_z_axis)——过渡动画参考页与性能测试的transitions主题直接呼应。
每个 demo 用 GalleryDemo(含 title / slug / icon / configurations)与 GalleryDemoConfiguration(含文档链接和 WidgetBuilder buildRoute)两个数据模型描述,describe 字段生成形如 slug@category 的稳定标识——这也是性能测试中 demoDescriptions 消息返回的列表元素格式。
3.2 路由机制与 Web 适配
lib/routes.dart 定义了一个基于正则的轻量路由表:RouteConfiguration.paths 是一组 Path(pattern, builder),按列表顺序匹配(越靠前优先级越高),首个匹配即构建页面;在 lib/main.dart 中通过 MaterialApp.onGenerateRoute 挂接。值得注意的是其对 Web 的特殊处理:当 kIsWeb 为真时返回 NoAnimationMaterialPageRoute(重写 buildTransitions 直接返回 child),因为浏览器地址栏导航不应伴随路由动画。
3.3 延迟加载(deferred libraries)
工程大量使用 Dart 的 deferred as 导入来拆分页面代码,例如 lib/routes.dart 对 crane、rally、fortnightly、shrine 的 app 均为 import ... deferred,实际构建时用 DeferredWidget 包裹,加载时显示 DeferredLoadingPlaceholder。lib/data/demos.dart 还提供了一个测试辅助函数 pumpDeferredLibraries(),等待全部延迟库预加载完成——保证 widget 测试不受懒加载时序影响。这一机制说明即便处于弃用状态,该工程仍是仓库内验证“deferred components / 代码拆分”行为的活样本。
3.4 依赖与资源
dev/integration_tests/new_gallery/pubspec.yaml 中 name: gallery、version: 2.10.2+021002(注释指明版本号含义见 README)。运行时依赖包括 flutter、flutter_localizations、google_fonts(main.dart 中显式 GoogleFonts.config.allowRuntimeFetching = false,改为纯本地字体以保证可离线运行)、provider / scoped_model、animations 等;素材则来自三个独立的 assets 包:flutter_gallery_assets(含 Crane 目的地图片、Splash 动效 GIF、Study 卡片图与 Google Fonts 字体的大量本地化文件)、shrine_images、rally_assets。这些包统一由仓库根 workspace 锁定版本,见根 pubspec.yaml 的 flutter_gallery_assets: 1.0.2、shrine_images: 2.0.2、rally_assets: 3.0.1。
四、官方推荐的替代学习资源
既然 Gallery 已退出“帮助开发者评估 Flutter”的职责,README 明确推荐开发者转向以下四类官方资源(此处保留原文档的完整清单与说明,仅按规范不附外部链接):
| 替代资源 | 官方定位(README 原文含义) |
|---|---|
| Wonderous | 展示 Flutter 对优雅设计与丰富动画支持的 Flutter 应用,提供 Web demo、App Store、Google Play 与源码仓库 |
| Material 3 Demo | 展示 Flutter Material 库中 Material 3 特性的 Flutter 应用,提供 Web demo 与源码 |
| Flutter Samples | 一组展示 Flutter 最佳实践(best practices)的开源示例集合 |
| Widget catalogs | Material 与 Cupertino 等可用 UI 控件的官方目录(Widget Catalog),可按控件逐一浏览 |
对仓库内的读者而言,还有一条更直接的替代路径:本仓库的 examples/ 目录提供了 hello_world、platform_channel、platform_view、layers 等官方示例,而 packages/flutter/examples 下的 API 示例集(API examples)则覆盖了绝大多数 API 的最小可运行用法。
五、如何查看与运行(只读视角)
以下操作仅涉及本地克隆后的查看与测试运行,不要求修改仓库:
-
在 CI 中它如何被触发:devicelab 以任务脚本方式运行,例如 Android 过渡基准的入口是 new_gallery__transition_perf.dart,其中
deviceOperatingSystem = DeviceOperatingSystem.android,并以 20 分钟超时执行NewGalleryPerfTest().run(注释说明该超时用于留出截图排障时间,关联 issue 114025)。 -
手工跑性能测试:在克隆的 Flutter 仓库根目录执行 devicelab 任务(需要已配置的设备/模拟器与 devicelab 依赖):
# 在仓库根目录,示例:运行 Android 过渡动画基准 flutter/bin/flutter drive \ --target=dev/integration_tests/new_gallery/test_driver/transitions_perf.dart \ dev/integration_tests/new_gallery/test_driver/transitions_perf_test.dart或者按 devicelab 规范直接以任务脚本方式调度;
--dart-define=onlyCrane=true/onlyReply=true可将基准范围收敛到单一 study,与 CI 中的 crane 专属任务对齐。 -
跑 widget 级测试:工程自带 test/(含
demo_descriptions_test.dart、theme_test.dart、pages/home_test.dart),可在dev/integration_tests/new_gallery目录下用标准flutter test执行;测试中通过pumpDeferredLibraries()预加载延迟库。 -
查看性能数据:各渲染后端的帧时间对比数据由
new_gallery*系列任务产出并上报,docs/engine/impeller/docs/benchmarks.md 列出了对应的 dashboard 查询口径(平均、90 分位、99 分位、最差帧光栅化时间)。
六、小结
New Gallery 的故事是“展示应用 → 性能基准”的典型生命周期:README 用最短的篇幅完成了弃用声明与资源交接(Wonderous、Material 3 Demo、Flutter Samples、Widget catalogs),而仓库结构则补充了它弃用后仍然重要的另一面——它是 devicelab 五大平台、多渲染器(Skia / Impeller Vulkan / Impeller OpenGLES)过渡动画基准的被测对象,也是延迟加载、正则路由表、多 study 路由、本地化与资源分包等机制的现存参考实现。理解它当前的“测试资产”身份,比把它当作学习 Flutter 的入门应用更为准确。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0625
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00