33// found in the LICENSE file.
44
55import 'dart:convert' ;
6+ import 'dart:typed_data' ;
67
7- import 'package:flutter/foundation.dart' ;
8- import 'package:flutter/services.dart' show PlatformAssetBundle;
8+ import 'package:flutter/services.dart' show PlatformAssetBundle, StandardMessageCodec;
99import 'package:flutter/widgets.dart' ;
1010
1111import '../common.dart' ;
@@ -18,16 +18,14 @@ void main() async {
1818 final BenchmarkResultPrinter printer = BenchmarkResultPrinter ();
1919 WidgetsFlutterBinding .ensureInitialized ();
2020 final Stopwatch watch = Stopwatch ();
21- final PlatformAssetBundle bundle = PlatformAssetBundle ();
2221
23- final ByteData assetManifestBytes = await bundle.load ('money_asset_manifest.json' );
22+ final ByteData assetManifest = await loadAssetManifest ();
23+
2424 watch.start ();
2525 for (int i = 0 ; i < _kNumIterations; i++ ) {
26- bundle.clear ();
27- final String json = utf8.decode (assetManifestBytes.buffer.asUint8List ());
28- // This is a test, so we don't need to worry about this rule.
26+ // This is effectively a test.
2927 // ignore: invalid_use_of_visible_for_testing_member
30- await AssetImage .manifestParser (json );
28+ AssetImage .parseAssetManifest (assetManifest );
3129 }
3230 watch.stop ();
3331
@@ -40,3 +38,49 @@ void main() async {
4038
4139 printer.printToStdout ();
4240}
41+
42+ final RegExp _extractRatioRegExp = RegExp (r'/?(\d+(\.\d*)?)x$' );
43+
44+ Future <ByteData > loadAssetManifest () async {
45+ double parseScale (String key) {
46+ final Uri assetUri = Uri .parse (key);
47+ String directoryPath = '' ;
48+ if (assetUri.pathSegments.length > 1 ) {
49+ directoryPath = assetUri.pathSegments[assetUri.pathSegments.length - 2 ];
50+ }
51+ final Match ? match = _extractRatioRegExp.firstMatch (directoryPath);
52+ if (match != null && match.groupCount > 0 ) {
53+ return double .parse (match.group (1 )! );
54+ }
55+ return 1.0 ;
56+ }
57+
58+ final Map <String , dynamic > result = < String , dynamic > {};
59+ final PlatformAssetBundle bundle = PlatformAssetBundle ();
60+
61+ // For the benchmark, we use the older JSON format and then convert it to the modern binary format.
62+ final ByteData jsonAssetManifestBytes = await bundle.load ('money_asset_manifest.json' );
63+ final String jsonAssetManifest = utf8.decode (jsonAssetManifestBytes.buffer.asUint8List ());
64+
65+ final Map <String , dynamic > assetManifest = json.decode (jsonAssetManifest) as Map <String , dynamic >;
66+
67+ for (final MapEntry <String , dynamic > manifestEntry in assetManifest.entries) {
68+ final List <dynamic > resultVariants = < dynamic > [];
69+ final List <String > entries = (manifestEntry.value as List <dynamic >).cast <String >();
70+ for (final String variant in entries) {
71+ if (variant == manifestEntry.key) {
72+ // With the newer binary format, don't include the main asset in it's
73+ // list of variants. This reduces parsing time at runtime.
74+ continue ;
75+ }
76+ final Map <String , dynamic > resultVariant = < String , dynamic > {};
77+ final double variantDevicePixelRatio = parseScale (variant);
78+ resultVariant['asset' ] = variant;
79+ resultVariant['dpr' ] = variantDevicePixelRatio;
80+ resultVariants.add (resultVariant);
81+ }
82+ result[manifestEntry.key] = resultVariants;
83+ }
84+
85+ return const StandardMessageCodec ().encodeMessage (result)! ;
86+ }
0 commit comments