Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 5ca4dfa

Browse files
committed
Add benchmarks and baselines
1 parent 601c124 commit 5ca4dfa

File tree

9 files changed

+116
-56
lines changed

9 files changed

+116
-56
lines changed

benchmark/README.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# Performance profiling
2+
3+
Run the following to gather new benchmark data:
4+
5+
```text
6+
$ flutter drive --target=benchmark/app.dart --driver=benchmark/app_benchmark.dart --profile --endless-trace-buffer
7+
```
8+
9+
Install Benchmarkhor (`pub global activate benchmarkhor`), then run:
10+
11+
```text
12+
$ benchextract benchmark/*.json
13+
```
14+
15+
Finally, compare different benchmark runs with
16+
17+
```text
18+
$ benchcompare benchmark/some-baseline.benchmark benchmark/new.benchmark
19+
```

benchmark/app.dart

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ void main() {
1212
// This line enables the extension.
1313
enableFlutterDriverExtension();
1414

15-
/// Create core models & services
15+
// Create core models & services
16+
// TODO: remove dependency on networking by mocking these
1617
FirebaseService firebase = FirebaseFactory.create();
1718
BooksModel booksModel = BooksModel();
1819
AppModel appModel = AppModel(booksModel, firebase);
@@ -29,24 +30,6 @@ void main() {
2930
// BooksModel - Stores data about the content in the app
3031
ChangeNotifierProvider.value(value: booksModel),
3132
],
32-
33-
//child: BasicRouterSpike(),
3433
child: AppBootstrapper(),
3534
));
36-
// // Call the `main()` function of the app, or call `runApp` with
37-
// // any widget you are interested in testing.
38-
// // TODO: remove dependency on networking
39-
// runApp(
40-
// ChangeNotifierProvider(
41-
// create: (_) => BooksModel(),
42-
// child: MaterialApp(
43-
// home: Scaffold(
44-
// body: Builder(builder: (context) {
45-
// Commands.setContext(context);
46-
// return BooksHomePage();
47-
// }),
48-
// ),
49-
// ),
50-
// ),
51-
// );
5235
}

benchmark/app_benchmark.dart

Lines changed: 81 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,6 @@ import 'package:test/test.dart';
66

77
void main() {
88
group('Full app', () {
9-
final styledPageScaffold = find.byValueKey('StyledPageScaffold');
10-
final authSubmitButton = find.byValueKey('auth_submit_button');
11-
129
late FlutterDriver driver;
1310

1411
// Connect to the Flutter driver before running any tests.
@@ -21,26 +18,91 @@ void main() {
2118
driver.close();
2219
});
2320

24-
test('StyledPageScaffold appears after login and scrolls', () async {
21+
test(
22+
'homepage scrolling up and down',
23+
() async {
24+
await _ensureLoggedIn(driver);
25+
26+
await driver.startTracing(streams: [TimelineStream.embedder]);
27+
for (var i = 0; i < 10; i++) {
28+
// Scroll about 6 pages down ...
29+
await driver.scroll(
30+
styledPageScaffold, 0, -6000, const Duration(seconds: 1));
31+
await driver.tap(styledPageScaffold);
32+
// ... and about 5 pages up.
33+
await driver.scroll(
34+
styledPageScaffold, 0, 5000, const Duration(seconds: 2));
35+
await driver.tap(styledPageScaffold);
36+
}
37+
final timeline = await driver.stopTracingAndDownloadTimeline();
38+
await _saveTimeline('homepage-scrolling', timeline);
39+
},
40+
timeout: _increasedTimeout,
41+
skip: 'currently only have one folio, so no scrolling',
42+
);
43+
44+
test('going from login screen to homepage and back', () async {
45+
await _ensureLoggedIn(driver);
46+
2547
await driver.startTracing(streams: [TimelineStream.embedder]);
26-
await driver.waitFor(authSubmitButton);
27-
await driver.tap(authSubmitButton);
28-
await driver.waitFor(styledPageScaffold);
29-
for (var i = 0; i < 10; i++) {
30-
await driver.scroll(
31-
styledPageScaffold, 0, -6000, const Duration(seconds: 1));
32-
await driver.tap(styledPageScaffold);
33-
await driver.scroll(
34-
styledPageScaffold, 0, 5000, const Duration(seconds: 2));
35-
await driver.tap(styledPageScaffold);
48+
for (var i = 0; i < 50; i++) {
49+
// Log out ...
50+
await driver.tap(roundedProfileButton);
51+
await driver.tap(logoutButton);
52+
// ... then log in again.
53+
await driver.tap(authSubmitButton);
3654
}
3755
final timeline = await driver.stopTracingAndDownloadTimeline();
3856

39-
final now = DateTime.now();
40-
final nowString = now.toIso8601String().replaceAll(':', '-');
41-
final file = File('benchmark/timeline-$nowString.json');
42-
await file.writeAsString(json.encode(timeline.json));
57+
await _saveTimeline('login-to-homepage', timeline);
58+
}, timeout: _increasedTimeout);
59+
60+
test('opening and closing the "create new" sheet', () async {
61+
await _ensureLoggedIn(driver);
62+
63+
await driver.startTracing(streams: [TimelineStream.embedder]);
64+
for (var i = 0; i < 50; i++) {
65+
// Open ...
66+
await driver.tap(newFolioFab);
67+
// ... and close.
68+
await driver.scroll(
69+
newFolioCard, 0, 5000, const Duration(milliseconds: 200));
70+
}
71+
final timeline = await driver.stopTracingAndDownloadTimeline();
4372

44-
}, timeout: Timeout(const Duration(minutes: 3)));
73+
await _saveTimeline('create-new-sheet', timeline);
74+
}, timeout: _increasedTimeout);
4575
});
4676
}
77+
78+
final authSubmitButton = find.byValueKey('auth_submit_button');
79+
final logoutButton = find.byValueKey('logout_button');
80+
final materialApp = find.byType('MaterialApp');
81+
final newFolioFab = find.byType('_NewFolioFab');
82+
final newFolioCard = find.byType('_NewFolioCard');
83+
final roundedProfileButton = find.byValueKey('rounded_profile_button');
84+
final styledPageScaffold = find.byValueKey('StyledPageScaffold');
85+
86+
final Timeout _increasedTimeout = Timeout(const Duration(minutes: 5));
87+
88+
Future<void> _ensureLoggedIn(FlutterDriver driver) async {
89+
// await driver.waitFor(find.byType('MainAppScaffold'));
90+
91+
// XXX: The following currently always returns an empty string.
92+
// We basically have no way of programmatically learning if we're
93+
// logged in or out.
94+
// final renderTree = await driver.getRenderTree();
95+
// print('render tree:');
96+
// print(renderTree.tree);
97+
98+
if (false) {
99+
await driver.tap(authSubmitButton);
100+
}
101+
}
102+
103+
Future<void> _saveTimeline(String label, Timeline timeline) async {
104+
final now = DateTime.now();
105+
final nowString = now.toIso8601String().replaceAll(':', '-');
106+
final file = File('benchmark/$label-$nowString.json');
107+
await file.writeAsString(json.encode(timeline.json));
108+
}
9.09 KB
Binary file not shown.
7.96 KB
Binary file not shown.

lib/views/app_title_bar/app_title_bar.dart

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,19 @@ class _AdaptiveTitleBarContent extends StatelessWidget {
5050
Spacer(),
5151
if (showTouchToggle) TouchModeToggleBtn(invertPopupAlign: isMac),
5252
HSpace.sm,
53-
RoundedProfileBtn(invertRow: true, useBottomSheet: isMobile),
53+
RoundedProfileBtn(
54+
key: _profileBtnKey,
55+
invertRow: true,
56+
useBottomSheet: isMobile,
57+
),
5458
HSpace.sm,
5559
] else ...[
5660
HSpace.sm,
5761
// Linux and Windows are left aligned and simple
58-
RoundedProfileBtn(useBottomSheet: isMobile),
62+
RoundedProfileBtn(
63+
key: _profileBtnKey,
64+
useBottomSheet: isMobile,
65+
),
5966
HSpace.sm,
6067
if (showTouchToggle) TouchModeToggleBtn(invertPopupAlign: isMac),
6168
HSpace.sm,
@@ -65,6 +72,8 @@ class _AdaptiveTitleBarContent extends StatelessWidget {
6572
),
6673
]);
6774
}
75+
76+
static Key _profileBtnKey = Key('rounded_profile_button');
6877
}
6978

7079
class _TitleText extends StatelessWidget {

lib/views/home_page/covers_flow_list_mobile.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ class _CoversFlowListMobileState extends State<CoversFlowListMobile> {
3939
scrollDirection: Axis.vertical,
4040
itemBuilder: (_, index) => BookCoverWidget(widget.books[index], largeMode: true),
4141
),
42-
if (_isResting)
42+
if (_isResting && nextBook != null)
4343
Positioned.fill(
4444
child: FadeInUp(
4545
child: FractionalTranslation(
@@ -48,7 +48,7 @@ class _CoversFlowListMobileState extends State<CoversFlowListMobile> {
4848
offset: Offset(0, -150),
4949
child: Transform.scale(
5050
scale: .9,
51-
child: BookCoverWidget(nextBook!, topTitle: true),
51+
child: BookCoverWidget(nextBook, topTitle: true),
5252
)),
5353
),
5454
),

lib/views/user_profile_card/user_profile_form.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ class _UserProfileFormState extends State<UserProfileForm> {
9494
children: [
9595
Expanded(child: UiText(text: _user?.email, style: TextStyles.body3)),
9696
PrimaryBtn(
97+
key: Key('logout_button'),
9798
icon: Icons.logout,
9899
leadingIcon: false,
99100
label: "LOGOUT",

pubspec.lock

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -889,13 +889,6 @@ packages:
889889
url: "https://pub.dartlang.org"
890890
source: hosted
891891
version: "1.0.0"
892-
quiver:
893-
dependency: transitive
894-
description:
895-
name: quiver
896-
url: "https://pub.dartlang.org"
897-
source: hosted
898-
version: "3.0.1"
899892
random_color:
900893
dependency: "direct main"
901894
description:
@@ -1097,13 +1090,6 @@ packages:
10971090
url: "https://pub.dartlang.org"
10981091
source: hosted
10991092
version: "1.0.0"
1100-
t_stats:
1101-
dependency: "direct dev"
1102-
description:
1103-
name: t_stats
1104-
url: "https://pub.dartlang.org"
1105-
source: hosted
1106-
version: "3.0.0"
11071093
term_glyph:
11081094
dependency: transitive
11091095
description:

0 commit comments

Comments
 (0)