共計 3223 個字符,預(yù)計需要花費 9 分鐘才能閱讀完成。
本文丸趣 TV 小編為大家詳細介紹“Flutter 瘦身怎么實現(xiàn)”,內(nèi)容詳細,步驟清晰,細節(jié)處理妥當,希望這篇“Flutter 瘦身怎么實現(xiàn)”文章能幫助大家解決疑惑,下面跟著丸趣 TV 小編的思路慢慢深入,一起來學(xué)習新知識吧。
下面我們以 ios 端為例分析項目中 flutter 產(chǎn)物的大小(ipa 包瘦身需求更為急切)。
ios 工程對 Flutter 有如下依賴:
Flutter.framework : Flutter 庫和引擎
App.framework: dart 業(yè)務(wù)源碼相關(guān)文件
Flutter Plugin:編譯出來的各種 plugin 的 framework
flutter_assets:Flutter 依賴的靜態(tài)資源,如字體,圖片等
第一次引入 flutter 版本改造詳情頁后,ipa 包大小增加近 20M,其中包括 flutter 引擎代碼 + 被改造業(yè)務(wù)代碼,繼續(xù)發(fā)布頁 flutter 改造后,ipa 增加 4M+。進一步分析解壓 ipa 文件后發(fā)現(xiàn) Flutter.framework 穩(wěn)定保持在 20M+ 的大小, 增加新的 flutter 業(yè)務(wù)——發(fā)布頁之后,App.framework 增幅近 10M!
Flutter.framework 是 Flutter 庫和引擎的代碼,我們能做的優(yōu)化空間有限,先把目標放在 dart 業(yè)務(wù)相關(guān)的文件 App.framework 上。
Flutter 產(chǎn)物大小分析
執(zhí)行如下命令編譯出一個 release 模式下的 App.framework,并使用 print-snapshot-sizes 參數(shù)打印出產(chǎn)物具體大小
flutter build aot --release --extra-gen-snapshot-options=--print-snapshot-sizes
結(jié)果如下:
Building AOT snapshot in release mode (android-arm-release)...
VMIsolate(CodeSize): 4660
Isolate(CodeSize): 2585632
ReadOnlyData(CodeSize): 2693576
Instructions(CodeSize): 8064816
Total(CodeSize): 13348684
Built to build/aot/.
Instructions:代表 AOT 編譯后生成的二進制代碼大小
ReadOnlyData:代表生成二進制代碼的元數(shù)據(jù)(例如 PcDescriptor,StackMap,CodeSourceMap 等)和字符串大小
VMIsolate/Isolate:代表剩下的對象的大小總和(例如代碼中定義的常量和虛擬機特定元數(shù)據(jù))
具體到業(yè)務(wù)層,想要分析各個業(yè)務(wù)模塊所占用的大小該怎么辦呢?
執(zhí)行如下命令編譯出一個 arm64 架構(gòu)的 App.framework, 并將它的包組成結(jié)構(gòu)放到指定目錄 build/aot.json 文件中
flutter --suppress-analytics build aot --output-dir=build/aot --target-platform=ios --target=lib/main.dart --release --ios-arch=arm64 --extra-gen-snapshot-options= --dwarf_stack_traces,--print-snapshot-sizes,--print_instructions_sizes_to=build/aot.json
使用 dart 命令將上一步生成的 aot.json 文件轉(zhuǎn)化成結(jié)構(gòu)可視化的網(wǎng)頁
dart ./bin/run_binary_size_analysis.dart build/aot.json path_to_webpage_dir
run_binary_size_analysis.dart 是 dart 提供的一個分析工具,在 flutter 引擎源碼中路徑如下:
打開生成文件夾中的 index.html 即可分析具體業(yè)務(wù)所占用的大小,右上角的 Large Symbols 和 Large Files 按鈕可以直接定位體積占比從大到小的方法 / 文件。
舉個例子,上面的分析顯示 PItemInfoInternal.fromJson 方法占用了大量體積,跟蹤發(fā)現(xiàn)這個方法主要的操作是將 Map 數(shù)據(jù)轉(zhuǎn)化成對象
PItemInfoInternal.fromJson(Map dynamic, dynamic map) { id = map[ id] as String;
attributes = map[attributes] as String;
title = map[title] as String;
......
}
由此我們可以推斷這種類型轉(zhuǎn)換的操作會導(dǎo)致編譯生成一些體積很大的代碼。
優(yōu)化措施
減少顯示類型轉(zhuǎn)換操作
按照上述分析發(fā)現(xiàn)顯示的類型轉(zhuǎn)換 as String/Bool/Int 這類操作會導(dǎo)致 App.framework 體積顯著增加,主要是它會增加類型檢查以及拋出異常的處理邏輯:
if (x.classId A x.classId B) throw x is not subtype of String
通過提取靜態(tài)公用方法的方式可以成功減少 400k+ 體積。
通過編譯參數(shù) –dwarf_stack_trace 和 –obfuscate 減小生成代碼的體積
dwarf_stack_trace 表示在生成的動態(tài)庫文件中,不使用堆棧跟蹤符號
obfuscate 表示混淆,通過減少變量名 / 方法名的方式減小代碼體積
// 編譯 release 包并打印 size
flutter build aot --release --extra-gen-snapshot-options=--print-snapshot-sizes
//--dwarf_stack_traces, -- 減少 6.2% 大小
flutter build aot --release --extra-gen-snapshot-options= --dwarf_stack_traces,--print-snapshot-sizes
//--obsfuscation, -- 減少 2.5% 大小
flutter build aot --release --extra-gen-snapshot-options= --dwarf_stack_traces,--print-snapshot-sizes,--obfuscate
// 總大小減少 8.7%
通過修改 ios 打包腳本 xcode_backend.sh,刪除 dSYM 符號表信息文件,App.framework 成功減小 20% 的大小。dSYM 是保存 16 進制函數(shù)地址映射信息的中轉(zhuǎn)文件,包含我們調(diào)試的 symbols,用來分析 crash report 文件,解析出正確的錯誤函數(shù)信息。
使用 xcrun 命令將 dSYM 從 framework 中剝離出來,可以大大減小 App.framework 的體積。
RunCommand xcrun dsymutil -o ${build_dir}/aot/App.dSYM
減少 flutter 和 native 資源重復(fù)造成的體積增大
利用橋接的方式,flutter 直接使用 Platform 端資源文件,避免因為資源文件重復(fù)導(dǎo)致的包大小增加問題。
主要方式是通過 BasicMessageChannel 在 Flutter 和 Platform 端傳遞信息。Flutter 端將資源名 AssetName 傳遞給 Platform 端,Platform 端接收到 AssetName 后,根據(jù) name 定位到資源文件,并將該文件以二進制數(shù)據(jù)格式,通過 BasicMessageChannel 傳遞回 Flutter 端。
讀到這里,這篇“Flutter 瘦身怎么實現(xiàn)”文章已經(jīng)介紹完畢,想要掌握這篇文章的知識點還需要大家自己動手實踐使用過才能領(lǐng)會,如果想了解更多相關(guān)內(nèi)容的文章,歡迎關(guān)注丸趣 TV 行業(yè)資訊頻道。