尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Flutter 引擎磁盘占用追踪与调试:treemap 分析、devicelab 体积基准与 AOT 快照大小对比

Flutter 引擎磁盘占用追踪与调试:treemap 分析、devicelab 体积基准与 AOT 快照大小对比 Flutter 引擎磁盘占用追踪与调试treemap 分析、devicelab 体积基准与 AOT 快照大小对比【免费下载链接】flutterFlutter makes it easy and fast to build beautiful apps for mobile and beyond项目地址: https://gitcode.com/GitHub_Trending/flutter41/flutter本指南围绕 Flutter 仓库中引擎产物尤其是 Android 平台的libflutter.so、APK/IPA 安装包、icudtl.dat与 VM/isolate 快照的磁盘占用追踪方法展开。读完本文后你将掌握如何通过 CI 产物查看引擎各组件大小的 treemap、如何在本地用binary_size_treemap.sh自行生成 treemap、devicelab 上持续追踪 APK/IPA 体积的基准指标含义以及如何用gen_snapshot与compare_size.dart做 AOT 快照的逐方法字节级 diff 分析。为什么需要追踪引擎的磁盘占用Flutter 引擎的最终产物libflutter.so、iOS 的Flutter.framework、icudtl.dat、AOT 快照等直接决定了用户下载包的大小。Flutter 仓库为此提供了一套“从粗到细”的工具链treemap树状图把libflutter.so按符号/组件拆分成面积图直观看到每个组件对二进制体积的贡献devicelab 基准每次提交都在 CI 上编译 Flutter Gallery 与最小 hello_world 应用持续上报 APK/IPA 及其中关键产物的压缩/未压缩大小AOT 快照大小对比在改动 Dart 代码或引擎后用gen_snapshot的--print-instructions-sizes-to输出指令大小 JSON再用compare_size.dart生成“哪个库、哪个方法变大/变小了多少字节”的表格。这三层工具分别回答三个问题引擎里什么占地方、最近一次改动让安装包变大还是变小、具体是哪些 Dart 方法让 AOT 代码变大。Treemap查看libflutter.so的组件级大小分布CI 自动生成的 treemap在 CI 中每笔提交都会为 release 版本的libflutter.so生成 treemap图示其中各组件的相对大小。产物上传到对象存储并从 CI 构建页面链接出来。在构建系统中定位某个 commit 的 treemap 的步骤是打开 flutter/flutter 仓库 main 分支的 commit 列表找到要评估的 commit点击其绿色 checkbox 查看各项 check找到名为Linux linux_android_aot_engine的 check点击details点击View more details on flutter-dashboard进入 LUCI 构建页面展开名为launch builds的区域找到类似Linux Production Engine Drone for ci/android_release_arm64的被触发构建并点开在该构建的log links区域中找到并点击index.html链接即可打开 treemap。本地生成 treemap不想依赖 CI 时仓库内置的 binary_size_treemap.sh 可以在本地生成同样的 treemapflutter/ci/binary_size_treemap.sh path/to/libflutter.so output_directory注意flutter/ci是引擎源码目录内的路径即本仓库中的 engine/src/flutter/ci。从脚本源码看其工作方式它要求输入是libflutter.so一类的 ELF 动态库输出目录即 treemap HTML 的存放位置脚本会定位到引擎构建根目录ENGINE_BUILDROOT然后调用 Dart SDK 附带的二进制体积分析工具 run_binary_size_analysis.py命令核心为python3 $RUN_BINARY_SIZE_ANALYSIS --library $INPUT_PATH \ --destdir $DEST_DIR \ --addr2line-binary $ADDR2LINE \ --nm-binary $NM --jobs 1 --no-check-support它按主机系统macOS 用darwin-x86_64、Linux 用linux-x86_64选取 Android NDK 28.2.13676358 中的llvm-addr2line与llvm-nm见 binary_size_treemap.shnm用来枚举符号addr2line用来把地址区间映射回源码/符号名从而算出每个组件的体积贡献。因此该脚本需要在完整的引擎构建环境中运行能取到对应版本的 NDK 工具链。treemap 的用途是“定位大头”当某次提交导致libflutter.so明显变大时先在 treemap 中看是哪一块区域图形库、文本渲染、平台通道等面积增长再进入下一层工具做细粒度归因。devicelab 基准持续追踪 APK/IPA 与引擎产物大小Flutter 仓库的 dev/devicelab 中有一组针对包体积的基准测试随每笔提交运行结果展示在构建仪表盘上。与引擎大小最相关的指标有指标类别指标名suite__compile/metric形式含义Flutter Gallery 的 APK/IPA 总大小Android:flutter_gallery_android__compile/release_size_bytesiOS:flutter_gallery_ios__compile/release_size_bytes完整 Gallery 应用 release 安装包大小最小 hello_world 应用 APK/IPA 大小Android:hello_world_android__compile/release_size_bytesiOS:hello_world_ios__compile/release_size_bytes剥离业务代码后的“纯 Flutter”基线体积icudtl.dat大小压缩在 APK 内:hello_world_android__compile/icudtl_compressed_bytes未压缩:hello_world_android__compile/icudtl_uncompressed_bytesICU 数据文件的体积release 模式libflutter.so大小压缩在 APK 内:hello_world_android__compile/libflutter_compressed_bytes未压缩:hello_world_android__compile/libflutter_uncompressed_bytes引擎主体动态库的体积VM 与 isolate 快照数据 指令压缩在 APK 内:hello_world_android__compile/snapshot_compressed_bytes未压缩:hello_world_android__compile/snapshot_uncompressed_bytesAOT 快照产物的体积从源码结构看这些指标的产生位置devicelab 的编译基准统一由 perf_tests.dart 驱动。其中_compileApp方法负责 release 构建并上报总大小perf_tests.dartAndroid执行flutter build apk --release --target-platformandroid-arm --tree-shake-icons --split-debug-infoinfos/然后取build/app/outputs/flutter-apk/app-release.apk的文件大小作为release_size_bytesiOS/macOS执行flutter build ios|macos --release --tree-shake-icons --split-debug-infoinfos/找到 app bundle 后执行tar -zcf build/app.tar.gz app以该 tarball 大小模拟 IPA 体积源码注释说明这样做的目的是“验证 Dart 快照格式与数据布局的变化不会改变压缩体积”同时近似 IPA 大小Windows取生成的.exe文件大小。APK 内产物的逐项大小则由getSizesFromApk得到它运行unzip -v apk解析清单提取lib/armeabi-v7a/libflutter.so、lib/armeabi-v7a/libapp.so与assets/flutter_assets/NOTICES.Z的压缩/未压缩大小产出libflutter_compressed_bytes、libapp_compressed_bytes等指标perf_tests.dart。iOS 侧则从Frameworks/Flutter.framework/Flutter与App.framework/App读取未压缩大小perf_tests.dart。使用建议判断“整体是否变胖”看release_size_bytes两条曲线Gallery 反映真实世界、hello_world 反映引擎基线判断“引擎还是 Dart 侧变胖”看libflutter_*与snapshot_*的相对变化判断 ICU 数据变化看icudtl_*。对比 AOT 快照大小定位到具体 Dart 方法当snapshot_*指标出现明显变化或你主动修改了 Dart 代码/引擎编译器、想确认对 AOT 代码量的影响时仓库提供了逐方法粒度的对比流程完整步骤记录在 Comparing-AOT-Snapshot-Sizes.md。前提条件是该机器已完成引擎开发环境搭建见 Setting-up-the-Engine-development-environment.md下文用FLUTTER_ENGINE指代引擎源码根。第 1 步带--verbose构建 AOT 产物对应用执行flutter build aot并加--verbose。目的是从日志里找到gen_snapshot的实际调用参数然后补一个额外选项--print-instructions-sizes-to重新运行。如果用的是本地引擎构建flutter build还需加上--local-engine与--local-engine-host标志参见 Debugging-the-engine.md 中“用本地引擎运行 Flutter 应用”一节。重新运行gen_snapshot的示例SUMMARY_LOCATION是输出的 JSON 摘要文件路径$FLUTTER_ENGINE/out/host_debug_unopt/gen_snapshot \ --print-instructions-sizes-to$SUMMARY_LOCATION \ --causal_async_stacks \ --packages.packages \ --deterministic \ --snapshot_kindapp-aot-blobs \ --vm_snapshot_databuild/aot/vm_snapshot_data \ --isolate_snapshot_databuild/aot/isolate_snapshot_data \ --vm_snapshot_instructionsbuild/aot/vm_snapshot_instr \ --isolate_snapshot_instructionsbuild/aot/isolate_snapshot_instr \ build/aot/app.dill各关键参数含义--print-instructions-sizes-to把每个方法生成的指令大小按库/方法写入 JSON--snapshot_kindapp-aot-blobs生成 AOT 应用的四个快照产物VM/isolate 的 data 与 instructions其余--vm_snapshot_*/--isolate_snapshot_*参数指定四个输出文件路径build/aot/app.dill是输入 kernel 文件其余参数--packages、--deterministic、--causal_async_stacks应与你从flutter build aot --verbose日志中看到的原始调用保持一致这样才能公平对比。将SUMMARY_LOCATION文件另存为before.json。第 2 步引入变更后重新生成二选一修改 Dart 代码观察业务代码改动的影响或重新构建引擎以获得新的gen_snapshot观察编译器/运行时改动的影响。注意再次执行flutter build aot这一步不可跳过因为 AOT 编译在gen_snapshot之前还有一次 kernel 编译步骤参见 Custom-Flutter-Engine-Embedding-in-AOT-Mode.md 中“生成 kernel 快照”一节需要刷新 kernel 输入。重新运行gen_snapshot调用把结果存为after.json。第 3 步运行compare_size.dart生成差异表格用引擎构建输出中的 Dart SDK 运行比较工具$FLUTTER_ENGINE/out/host_debug_unopt/dart-sdk/bin/dart \ before.json \ after.json输出是按“库 / 方法 / 字节差”排序的表格正数表示方法变大负数表示变小末尾给出总量变化。示例输出截取自 Comparing-AOT-Snapshot-Sizes.md------------------------------------------------------------------------------------ | Library | Method | Diff (Bytes) | ------------------------------------------------------------------------------------ | dart:async | new ZoneSpecification.from | 2136 | | dart:async | runZoned | 1488 | | dart:async | new _CustomZone | 927 | ... | | [Stub] Type Test Type: class PopupMenuItem | -128 | | dart:io | new Directory | -211 | ------------------------------------------------------------------------------------ Total change 24036 bytes.从示例可以看出两点表格同时列出普通方法与[Stub]如类型测试 stub因此能区分“真实代码变多”和“运行时 stub 增减”每行给出精确的字节差配合总量行即可回答“这次改动到底让 AOT 代码净增多少”。工具链小结场景工具入口看libflutter.so里什么组件占体积treemapCI 构建页index.html或 binary_size_treemap.sh追踪提交间 APK/IPA 与libflutter.so、快照、icudtl.dat体积趋势devicelab 基准perf_tests.dart 上报的release_size_bytes、libflutter_*、snapshot_*、icudtl_*指标定位 AOT 快照变大的具体 Dart 方法gen_snapshot --print-instructions-sizes-tocompare_size.dartComparing-AOT-Snapshot-Sizes.md三层工具自上而下构成完整的体积回归排查路径先用 devicelab 曲线发现异常再用 treemap 圈定引擎内的大头组件最后用 AOT 快照对比把变化归因到具体方法从而支撑对引擎磁盘占用的持续监控与问题定位。【免费下载链接】flutterFlutter makes it easy and fast to build beautiful apps for mobile and beyond项目地址: https://gitcode.com/GitHub_Trending/flutter41/flutter创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表