Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit a2005ea

Browse files
liyuqianfluttergithubbot
authored andcommittedDec 6, 2019
Memory test on scrolling large images quickly (flutter#46184)
1 parent 42cb919 commit a2005ea

File tree

8 files changed

+148
-3
lines changed

8 files changed

+148
-3
lines changed
 
Loading

‎dev/benchmarks/macrobenchmarks/lib/common.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@ const String kCubicBezierRouteName = '/cubic_bezier';
77
const String kBackdropFilterRouteName = '/backdrop_filter';
88
const String kSimpleAnimationRouteName = '/simple_animation';
99
const String kPictureCacheRouteName = '/picture_cache';
10+
const String kLargeImagesRouteName = '/large_images';

‎dev/benchmarks/macrobenchmarks/lib/main.dart

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// found in the LICENSE file.
44

55
import 'package:flutter/material.dart';
6+
import 'package:macrobenchmarks/src/large_images.dart';
67
import 'package:macrobenchmarks/src/picture_cache.dart';
78

89
import 'common.dart';
@@ -13,24 +14,29 @@ import 'src/simple_animation.dart';
1314

1415
const String kMacrobenchmarks ='Macrobenchmarks';
1516

16-
void main() => runApp(MacrobenchmarksApp());
17+
void main() => runApp(const MacrobenchmarksApp());
1718

1819
class MacrobenchmarksApp extends StatelessWidget {
20+
const MacrobenchmarksApp({this.initialRoute = '/'});
21+
1922
@override
2023
Widget build(BuildContext context) {
2124
return MaterialApp(
2225
title: kMacrobenchmarks,
23-
initialRoute: '/',
26+
initialRoute: initialRoute,
2427
routes: <String, WidgetBuilder>{
2528
'/': (BuildContext context) => HomePage(),
2629
kCullOpacityRouteName: (BuildContext context) => CullOpacityPage(),
2730
kCubicBezierRouteName: (BuildContext context) => CubicBezierPage(),
2831
kBackdropFilterRouteName: (BuildContext context) => BackdropFilterPage(),
2932
kSimpleAnimationRouteName: (BuildContext conttext) => SimpleAnimationPage(),
30-
kPictureCacheRouteName: (BuildContext conttext) => PictureCachePage(),
33+
kPictureCacheRouteName: (BuildContext context) => PictureCachePage(),
34+
kLargeImagesRouteName: (BuildContext context) => LargeImagesPage(),
3135
},
3236
);
3337
}
38+
39+
final String initialRoute;
3440
}
3541

3642
class HomePage extends StatelessWidget {
@@ -75,6 +81,13 @@ class HomePage extends StatelessWidget {
7581
Navigator.pushNamed(context, kPictureCacheRouteName);
7682
},
7783
),
84+
RaisedButton(
85+
key: const Key(kLargeImagesRouteName),
86+
child: const Text('Large Images'),
87+
onPressed: () {
88+
Navigator.pushNamed(context, kLargeImagesRouteName);
89+
},
90+
),
7891
],
7992
),
8093
);
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// Copyright 2014 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import 'dart:async';
6+
import 'dart:typed_data';
7+
8+
import 'package:flutter/material.dart';
9+
10+
class LargeImagesPage extends StatelessWidget {
11+
@override
12+
Widget build(BuildContext context) {
13+
final ImageCache imageCache = PaintingBinding.instance.imageCache;
14+
imageCache.maximumSize = 30;
15+
imageCache.maximumSizeBytes = 50 << 20;
16+
return GridView.builder(
17+
itemCount: 1000,
18+
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3),
19+
itemBuilder: (BuildContext context, int index) => DummyImage(index),
20+
).build(context);
21+
}
22+
}
23+
24+
class DummyImage extends StatelessWidget {
25+
DummyImage(this.index) : super(key: ValueKey<int>(index));
26+
27+
@override
28+
Widget build(BuildContext context) {
29+
final Future<ByteData> pngData = _getPngData(context);
30+
31+
return FutureBuilder<ByteData>(
32+
future: pngData,
33+
builder: (BuildContext context, AsyncSnapshot<ByteData> snapshot) {
34+
// Use Image.memory instead of Image.asset to make sure that we're
35+
// creating many copies of the image to trigger the memory issue.
36+
return snapshot.data == null
37+
? Container()
38+
: Image.memory(snapshot.data.buffer.asUint8List());
39+
},
40+
);
41+
}
42+
43+
final int index;
44+
45+
Future<ByteData> _getPngData(BuildContext context) async {
46+
return DefaultAssetBundle.of(context).load('assets/999x1000.png');
47+
}
48+
}

‎dev/benchmarks/macrobenchmarks/pubspec.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,5 +90,6 @@ flutter:
9090
assets:
9191
- packages/flutter_gallery_assets/food/butternut_squash_soup.png
9292
- packages/flutter_gallery_assets/food/cherry_pie.png
93+
- assets/999x1000.png
9394

9495
# PUBSPEC CHECKSUM: 4cef
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// Copyright 2014 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import 'dart:async';
6+
7+
import 'package:flutter/material.dart';
8+
import 'package:flutter/scheduler.dart';
9+
import 'package:flutter_test/flutter_test.dart';
10+
import 'package:macrobenchmarks/common.dart';
11+
import 'package:macrobenchmarks/main.dart';
12+
13+
Future<void> endOfAnimation() async {
14+
do {
15+
await SchedulerBinding.instance.endOfFrame;
16+
} while (SchedulerBinding.instance.hasScheduledFrame);
17+
}
18+
19+
int iteration = 0;
20+
21+
class LifecycleObserver extends WidgetsBindingObserver {
22+
@override
23+
void didChangeAppLifecycleState(AppLifecycleState state) {
24+
debugPrint('==== MEMORY BENCHMARK ==== $state ====');
25+
debugPrint('This was lifecycle event number $iteration in this instance');
26+
}
27+
}
28+
29+
Future<void> main() async {
30+
runApp(const MacrobenchmarksApp(initialRoute: kLargeImagesRouteName));
31+
await endOfAnimation();
32+
await Future<void>.delayed(const Duration(milliseconds: 50));
33+
debugPrint('==== MEMORY BENCHMARK ==== READY ====');
34+
WidgetsBinding.instance.addObserver(LifecycleObserver());
35+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// Copyright 2014 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import 'dart:async';
6+
7+
import 'package:flutter_devicelab/framework/adb.dart';
8+
import 'package:flutter_devicelab/framework/framework.dart';
9+
import 'package:flutter_devicelab/framework/utils.dart';
10+
import 'package:flutter_devicelab/tasks/perf_tests.dart';
11+
12+
const String kPackageName = 'com.example.macrobenchmarks';
13+
const String kActivityName = 'com.example.macrobenchmarks.MainActivity';
14+
15+
class FastScrollLargeImagesMemoryTest extends MemoryTest {
16+
FastScrollLargeImagesMemoryTest()
17+
: super(
18+
'${flutterDirectory.path}/dev/benchmarks/macrobenchmarks',
19+
'test_memory/large_images.dart', kPackageName,
20+
);
21+
22+
@override
23+
AndroidDevice get device => super.device;
24+
25+
@override
26+
int get iterationCount => 5;
27+
28+
@override
29+
Future<void> useMemory() async {
30+
await launchApp();
31+
await recordStart();
32+
await device.shellExec('input', <String>['swipe', '0 1500 0 0 50']);
33+
await Future<void>.delayed(const Duration(milliseconds: 10000));
34+
await recordEnd();
35+
}
36+
}
37+
38+
Future<void> main() async {
39+
deviceOperatingSystem = DeviceOperatingSystem.android;
40+
await task(FastScrollLargeImagesMemoryTest().run);
41+
}

‎dev/devicelab/manifest.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -670,6 +670,12 @@ tasks:
670670
stage: devicelab
671671
required_agent_capabilities: ["linux/android"]
672672

673+
fast_scroll_large_images__memory:
674+
description: >
675+
Measures memory usage for scrolling through a list of large images.
676+
stage: devicelab
677+
required_agent_capabilities: ["mac/android"]
678+
673679
analyzer_benchmark:
674680
description: >
675681
Measures the speed of Dart analyzer.

0 commit comments

Comments
 (0)
Please sign in to comment.