news 2026/9/19 13:45:36

web_benchmarks testing 目录运行指南:Flutter Web 基准测试的客户端-服务器端到端实践

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
web_benchmarks testing 目录运行指南:Flutter Web 基准测试的客户端-服务器端到端实践

web_benchmarks testing 目录运行指南:Flutter Web 基准测试的客户端-服务器端到端实践

【免费下载链接】packagesA collection of useful packages maintained by the Flutter team项目地址: https://gitcode.com/GitHub_Trending/pac/packages

本文以web_benchmarks包内置的 testing 目录运行说明 为主线,完整梳理"如何在本仓库中运行 Flutter Web 基准测试",并深入到 browser.dart、runner.dart、client.dart 等源码,还原从 Chrome 定位、应用构建、性能追踪到指标收率的完整链路。读完本文,你既能照搬命令跑通 testing 目录下的全部基准测试,也能理解 web_benchmarks 的客户端-服务器协作模型与指标计算原理,为在自己的 Flutter Web 应用中编写与接入基准测试打下基础。

一、testing 目录与 web_benchmarks 框架概览

web_benchmarks是 Flutter 团队维护的 Flutter Web 基准测试工具包,当前仅支持在 Chrome 中运行基准(详见 包级 README)。仓库中的 testing 目录 是一个完整的基准测试示例工程:

  • test_app:一个可运行的 Flutter Web 示例应用(含lib/main.dartlib/home_page.dartlib/about_page.dart),其benchmark子目录下存放基准测试用例;
  • web_benchmarks_test.dart:核心测试文件,驱动真实 Chrome 运行滚动、翻页、点击等基准;
  • 其余为测试基础设施(benchmark/test_infra/)。

testing 目录下的基准采用客户端-服务器(client-server)模型,这一点与integration_test包的思路类似:一端是在浏览器内与被测应用一起运行的客户端代码,另一端是负责构建产物、托管静态资源、并通过 Chrome DevTools 协议提取性能追踪数据的服务器(详见 包级 README 及 server.dart 的serveWebBenchmark文档注释)。后续章节会先给出官方推荐的运行步骤,再逐层剖析其内部机制。

二、运行前提:让测试能找到 Chrome

testing 目录的测试需要真实的 Chrome 浏览器,测试框架通过Chrome.launch启动它(browser.dart)。因此第一步是"安装一个测试可以找到的 Chrome"。

从源码看,Chrome 可执行文件的定位逻辑位于_findSystemChromeExecutable(browser.dart),其查找顺序如下:

平台查找方式
任意平台优先读取环境变量CHROME_EXECUTABLE(适用于 CI 等 Chrome 位于非标准路径的环境)
Linux执行which google-chrome,找不到则抛出Failed to locate system Chrome installation.
macOS固定路径/Applications/Google Chrome.app/Contents/MacOS/Google Chrome
Windows依次探测LOCALAPPDATAPROGRAMFILESPROGRAMFILES(X86)下的Google\Chrome\Application\chrome.exe

此外还有两个环境变量会影响启动行为(browser.dart):

  • CHROME_NO_SANDBOX=true:追加--no-sandbox启动参数;
  • 在 Linux 无显示器环境(如 CI)下配合headless: true使用,此时还会追加--use-gl=angle--use-angle=swiftshader--enable-unsafe-swiftshader--disable-gpu-sandbox等软件渲染参数。

在本地开发机上,通常只需安装好系统 Chrome 即可满足查找条件。

三、三步运行 testing 目录测试(官方步骤)

在满足 Chrome 前提后,按官方 testing README 依次执行以下命令。

第 1 步:拉取 test_app 的依赖

flutter pub get --directory testing/test_app

该命令在testing/test_app目录(pubspec.yaml)下执行flutter pub get,拉取示例应用与基准测试用例所需的依赖。

第 2 步:拉取 web_benchmarks 包的依赖

在 web_benchmarks 包根目录 下执行:

flutter pub get

第 3 步:运行测试

flutter test testing

官方文档给出的参考输出如下(节选):

00:03 +0: Can run a web benchmark Launching Chrome. Launching Google Chrome 98.0.4758.102 Waiting for the benchmark to report benchmark profile. [CHROME]: [0215/133233.327761:ERROR:socket_posix.cc(150)] bind() failed: Address already in use (98) [CHROME]: [CHROME]: DevTools listening on ws://[::1]:10000/devtools/browser/4ef82be6-9b68-4fd3-ab90-cd603d25ceb1 Connecting to DevTools: ws://localhost:10000/devtools/page/21E7271507E9BC796B957E075515520F Connected to Chrome tab: (http://localhost:9999/index.html) Launching benchmark "scroll" Extracted 299 measured frames. Skipped 1 non-measured frames. Launching benchmark "page" [APP] Testing round 0... [APP] Testing round 1... ... [APP] Testing round 9... Extracted 490 measured frames. Skipped 0 non-measured frames. Launching benchmark "tap" [APP] Testing round 0... ... Received profile data 00:26 +1: All tests passed!

对这段输出做几点解读,帮助判断运行是否正常:

  • bind() failed: Address already in use (98)是开发机端口占用告警,属于测试过程中的常见噪音,不代表测试失败——框架随后仍成功连接到了 DevTools(ws://localhost:10000);
  • 默认端口约定:基准服务器端口9999、Chrome DevTools 调试端口10000,均定义于 runner.dart;
  • Extracted N measured frames.Skipped N non-measured frames.BlinkTraceSummary.fromJson打印(browser.dart),表示从 Chrome 性能追踪中成功解析出的有效帧数;
  • [APP] Testing round 0...系列输出经/print-to-console端点由浏览器端转发打印(runner.dart)。

注意:官方文档还提示,若上述步骤失效,可参考 CI 中web_benchmarks_test步骤当前的实际做法同步更新本文档(原始说明链接指向仓库根目录的.cirrus.yml,本仓库快照中未包含该文件,实际排错可结合 tool/run_tests.dart 的流程核对)。

四、测试内部到底发生了什么:构建、启动、追踪与收率

flutter test testing只是入口,真正的基准驱动逻辑在 web_benchmarks_test.dart 中,它通过serveWebBenchmark(server.dart)编排整个流程。该文件共注册了三个测试用例:

  1. Can run a web benchmark:依次运行appNavigate(翻页)、appScroll(滚动)、appTap(点击)三个基准,入口为benchmark/test_infra/client/app_client.dart
  2. Can run a web benchmark with an alternate benchmarkPath:使用benchmark/test_infra/client/simple_benchmark_path_client.dart,并传入自定义benchmarkPath,校验初始加载与重载时的expectedUrl指标;
  3. Can run a web benchmark with wasm:使用CompilationOptions.wasm()以 WebAssembly + skwasm 方式编译运行,校验isWasm指标。

每个用例都会对全部基准名 × 全部指标 × 全部统计计算组合做存在性断言,并验证totalUiFrame.average指标存在(web_benchmarks_test.dart)。

BenchmarkServer.run()(runner.dart)的完整流程为:

  1. 校验 flutter 可执行:通过ProcessManager.canRun('flutter')检查,若不在 PATH 中直接抛异常;
  2. 构建 Web 应用:执行flutter build web --profile -t <entryPoint>,并附带--dart-define=FLUTTER_WEB_ENABLE_PROFILING=truetreeShakeIcons=false时追加--no-tree-shake-iconsCompilationOptions.wasm()时追加--wasm --no-strip-wasm(对应 dart2wasm + skwasm,而默认CompilationOptions.js()对应 dart2js + CanvasKit,见 server.dart 文档说明);
  3. 托管静态资源:用shelf_static提供build/web目录,并对 HTML 响应附加Cross-Origin-Opener-Policy: same-originCross-Origin-Embedder-Policy: require-corp头,使页面处于 crossOriginIsolated 状态——skwasm 渲染器依赖 SharedArrayBuffer,且该状态能获得更高精度的计时器(runner.dart);
  4. 启动 Chrome:以 headless 模式 +--remote-debugging-port=10000启动,窗口默认 1024×1024(ChromeOptions默认值,见 browser.dart),随后通过 WebKit Inspection Protocol 连接 DevTools 并找到打开http://localhost:9999/index.html的标签页;
  5. 按序运行基准:服务器通过/next-benchmark逐个下发基准名,每个基准运行前调用/start-performance-tracingTracing.start,类别为blink,blink.user_timing,见 browser.dart),运行结束后/stop-performance-tracing取回追踪数据,并汇总为BenchmarkResults返回。

值得注意的是,头部ERROR:bind()告警并不会中断流程:Chrome 的 stderr 中DevTools listening ...这一行才是连接成功的信号,框架会阻塞等待该行出现(browser.dart)。

五、客户端-服务器协作模型与手动回退

测试期间,浏览器内运行的是 client.dart 提供的runBenchmarks客户端。它以LocalBenchmarkServerClient与服务器通过 REST 接口协作,核心端点如下(实现见 client.dart 与 runner.dart):

端点方向作用
POST /next-benchmark客户端 → 服务器上报基准名列表,领取下一个要运行的基准名
POST /start-performance-tracing?label=...客户端 → 服务器请求服务器通过 DevTools 协议开启 chrome://tracing
POST /stop-performance-tracing客户端 → 服务器停止追踪并取回原始 trace 数据
POST /profile-data客户端 → 服务器上报某个基准的 Profile 数据
POST /on-error客户端 → 服务器上报浏览器端异常,服务器会中止整个任务
POST /print-to-console客户端 → 服务器把浏览器端日志转发到服务器控制台

客户端在浏览器中的print与未捕获异常都会经 zone 规范转发给服务器(client.dart),这就是测试输出中[APP] Testing round 0...的来源。

该模型还内置了手动回退(manual fallback)机制:当服务器不可用(例如用flutter run直接调试而非走测试框架)时,/next-benchmark返回 404,客户端据此进入手动模式——页面上会渲染一个可点击的基准名列表,运行结果直接可视化打印在网页上(TimeseriesVisualization会用 canvas 绘制时序柱状图,见 client.dart)。这使得基准既可以自动化跑,也方便人工调试。

六、收集哪些指标:帧耗时与统计计算

基准数据最终以BenchmarkScore(metric, value)形式呈现,指标体系定义于 metrics.dart:

  • Flutter 帧级指标BenchmarkMetric枚举):preroll_frame(提交图层/图片前的预处理,含变换与裁剪计算)、apply_frame(向渲染器提交图层与图片信息)、draw_framePlatformDispatcher.onDrawFrame回调耗时)、flutter_frame.total_timeflutter_frame.build_timeflutter_frame.raster_time(分别对应 Flutter EngineFrameTimingtotalSpanbuildDurationrasterDuration);
  • UI 线程整体指标totalUiFrame.average,来自 Blink trace 中WebViewImpl::beginFrame(脚本执行)与updateAllLifecyclePhases(样式、布局、绘制、合成)两类事件的平均耗时之和(browser.dart);
  • 每个指标的统计计算BenchmarkMetricComputation.values,见 metrics.dart):averageoutlierAverageoutlierRationoise以及p50p90p95三个百分位。

统计采样数以kMeasuredSampleCount = 100为上限(common.dart),测试运行时打印的Extracted N measured frames.即来自该解析过程;若一个可测帧都解析不出来,会抛出 "No measured frames found in benchmark tracing data." 并提示可能原因(帧泵不够或 Chrome 追踪格式变更),同时把原始 trace 写入./chrome-trace.json便于排查(browser.dart)。

七、结果分析:计算增量与平均值

跑完基准得到 JSON 结果后,web_benchmarks还提供离线分析能力(见 包级 README 与 analysis.dart):

  • computeDelta(baseline, test):计算两份基准结果的差值,用于对比基线;
  • computeAverage(results...):计算多份结果的均值,用于多轮合并。

仓库 example/analyze_example.dart 给出了完整用法:用BenchmarkResults.parse读取 JSON 文件后调用上述函数,再把结果toJson()输出。该文件同样被包级 README 以<?code-excerpt>方式引用,是编写分析脚本的直接模板。

八、自动化:tool/run_tests.dart

仓库还提供了可脚本化的测试入口 tool/run_tests.dart,其执行逻辑与"三步法"完全对应:

  1. testing/test_app下执行flutter pub getflutter pub get --directory的等价实现);
  2. 在包根目录执行flutter test testing

此外该脚本目前只在 Linux 主机上实际运行(其他平台直接跳过),并预留了dart run tool/run_tests.dart的调用方式说明,适合接入自定义 CI 任务。需要说明的是,官方测试还包含包内 test/ 目录 下的单元测试(如browser_test.dartcomputations_test.dart等,另有 more_tests_in_testing_dir_test.dart 将 testing 目录纳入测试范围),flutter test testing主要针对端到端基准用例。

九、常见问题速查

  • Failed to locate system Chrome installation.:Linux 下which google-chrome找不到 Chrome,请安装 Chrome 或设置CHROME_EXECUTABLE环境变量指向可执行文件;
  • flutter executable is not runnableflutter不在 PATH 中,请修正环境;
  • Address already in use (98):多为开发机端口占用,属噪音;若 9999/10000 端口确实被占用导致连接失败,可通过serveWebBenchmarkbenchmarkServerPortchromeDebugPort参数调整;
  • No measured frames found in benchmark tracing data.:按错误提示检查基准是否正常泵帧,或确认近期 Chrome 版本是否变更了追踪数据格式,必要时核对 browser.dart 中BlinkTraceEvent的解析逻辑(调试时原始 trace 会保存在./chrome-trace.json)。

至此,从环境准备、三步运行、内部流程到结果分析,web_benchmarks testing 目录的完整运行链路已全部打通;后续如需编写自己的 Web 基准,可参照 web_benchmarks_test.dart 与 client.dart 的runBenchmarks接口进行扩展。

【免费下载链接】packagesA collection of useful packages maintained by the Flutter team项目地址: https://gitcode.com/GitHub_Trending/pac/packages

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/19 13:45:31

Dolphin PDF转Markdown:一条命令完整跑通

Dolphin PDF转Markdown&#xff1a;一条命令完整跑通 【免费下载链接】Dolphin The official repo for “Dolphin: Document Image Parsing via Heterogeneous Anchor Prompting”, ACL, 2025. 项目地址: https://gitcode.com/GitHub_Trending/dolphin33/Dolphin Dolphi…

作者头像 李华
网站建设 2026/9/19 13:45:09

Keil MDK安装配置与调试避坑指南:从版本选择到工程管理

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/19 13:45:03

普通话轻声与儿化音的声学原理及自动化训练方案

简介&#xff1a;本资源是一份专为普通话水平测试&#xff08;PSC&#xff09;考生设计的权威发音训练文档&#xff0c;聚焦轻声与儿化音两大核心难点&#xff0c;适用于语言学习者、师范生、播音主持备考人员及教师教学参考。文档严格依据《普通话水平测试用普通话词语表》编制…

作者头像 李华
网站建设 2026/9/19 13:44:33

PLC控制电路设计:继电器逻辑映射与硬软协同安全实现

简介&#xff1a;本资源是一份面向电气自动化、机电一体化专业初学者及现场工程师的《电气控制和PLC基本控制电路》教学课件&#xff0c;系统覆盖电动机典型控制逻辑与低压电器应用核心技能。内容紧扣实际工程需求&#xff0c;深入解析点动与自锁、正反转、顺序起动、自动来回、…

作者头像 李华
网站建设 2026/9/19 13:42:41

N_m3u8DL-RE 完整指南:m3u8 与 MPD 流媒体下载、直播录制实操

N_m3u8DL-RE 完整指南&#xff1a;m3u8 与 MPD 流媒体下载、直播录制实操 【免费下载链接】N_m3u8DL-RE Cross-Platform, modern and powerful stream downloader for MPD/M3U8/ISM. English/简体中文/繁體中文. 项目地址: https://gitcode.com/GitHub_Trending/nm3/N_m3u8D…

作者头像 李华
网站建设 2026/9/19 13:42:25

半导体温差发电应急照明系统工程落地指南

简介&#xff1a;本资源是一份面向电子工程、自动化及新能源应用领域高校师生与科研人员的实用型技术方案&#xff0c;聚焦半导体温差发电在应急照明系统中的创新集成设计&#xff0c;解决大型公共场所&#xff08;如商场、医院、影院&#xff09;断电场景下传统应急电源响应滞…

作者头像 李华