From 86ac077fb546107ab307303e12781364cdb1798a Mon Sep 17 00:00:00 2001 From: hellohuanlin <41930132+hellohuanlin@users.noreply.github.com> Date: Mon, 8 Jul 2024 14:01:58 -0700 Subject: [PATCH] [ios]A typical news app benchmark with bottom ad banner (#150991) This is a very common usage of ad so we want to make sure it's performant. From the video, it scrolls quite smoothly, but we want to see the numbers, and keep monitoring it in case of regression. https://github.com/flutter/flutter/assets/41930132/c7811c15-ac07-4989-a8a9-3c128e08cbe0 *List which issues are fixed by this PR. You must list at least one issue. An issue is not required if the PR fixes something trivial like a typo.* Fixes https://github.com/flutter/flutter/issues/150230 *If you had to change anything in the [flutter/tests] repo, include a link to the migration guide as per the [breaking change policy].* --- .ci.yaml | 10 +++ TESTOWNERS | 1 + .../lib/main_bottom_ad_banner.dart | 83 +++++++++++++++++++ .../scroll_perf_bottom_ad_banner_test.dart | 59 +++++++++++++ ...kit_view_scroll_perf_bottom_ad_banner.dart | 13 +++ ...rf_bottom_ad_banner__timeline_summary.dart | 12 +++ dev/devicelab/lib/tasks/perf_tests.dart | 11 +++ 7 files changed, 189 insertions(+) create mode 100644 dev/benchmarks/platform_views_layout/lib/main_bottom_ad_banner.dart create mode 100644 dev/benchmarks/platform_views_layout/test_driver/scroll_perf_bottom_ad_banner_test.dart create mode 100644 dev/benchmarks/platform_views_layout/test_driver/uikit_view_scroll_perf_bottom_ad_banner.dart create mode 100644 dev/devicelab/bin/tasks/platform_views_scroll_perf_bottom_ad_banner__timeline_summary.dart diff --git a/.ci.yaml b/.ci.yaml index aed6c9ea16b40..0c2bc5a02185c 100644 --- a/.ci.yaml +++ b/.ci.yaml @@ -4808,6 +4808,16 @@ targets: ["devicelab", "ios", "mac"] task_name: platform_views_scroll_perf_ad_banners__timeline_summary + - name: Mac_ios platform_views_scroll_perf_bottom_ad_banner__timeline_summary + recipe: devicelab/devicelab_drone + presubmit: false + bringup: true + timeout: 60 + properties: + tags: > + ["devicelab", "ios", "mac"] + task_name: platform_views_scroll_perf_bottom_ad_banner__timeline_summary + - name: Mac_ios platform_views_scroll_perf_non_intersecting_impeller_ios__timeline_summary recipe: devicelab/devicelab_drone presubmit: false diff --git a/TESTOWNERS b/TESTOWNERS index 921fe8810d978..e643479d70ac1 100644 --- a/TESTOWNERS +++ b/TESTOWNERS @@ -211,6 +211,7 @@ /dev/devicelab/bin/tasks/platform_interaction_test_ios.dart @hellohuanlin @flutter/engine /dev/devicelab/bin/tasks/platform_view_ios__start_up.dart @stuartmorgan @flutter/plugin /dev/devicelab/bin/tasks/platform_views_scroll_perf_ad_banners__timeline_summary.dart @hellohuanlin @flutter/engine +/dev/devicelab/bin/tasks/platform_views_scroll_perf_bottom_ad_banner__timeline_summary.dart @hellohuanlin @flutter/engine /dev/devicelab/bin/tasks/platform_views_scroll_perf_ios__timeline_summary.dart @hellohuanlin @flutter/engine /dev/devicelab/bin/tasks/platform_views_scroll_perf_non_intersecting_impeller_ios__timeline_summary.dart @jonahwilliams @flutter/engine /dev/devicelab/bin/tasks/post_backdrop_filter_perf_ios__timeline_summary.dart @hellohuanlin @flutter/engine diff --git a/dev/benchmarks/platform_views_layout/lib/main_bottom_ad_banner.dart b/dev/benchmarks/platform_views_layout/lib/main_bottom_ad_banner.dart new file mode 100644 index 0000000000000..10249e1b8ea6a --- /dev/null +++ b/dev/benchmarks/platform_views_layout/lib/main_bottom_ad_banner.dart @@ -0,0 +1,83 @@ +// Copyright 2014 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'dart:io'; + +import 'package:flutter/material.dart'; +import 'package:google_mobile_ads/google_mobile_ads.dart'; + +void main() { + runApp( + const PlatformViewApp() + ); +} + +class PlatformViewApp extends StatefulWidget { + const PlatformViewApp({ + super.key, + }); + + @override + PlatformViewAppState createState() => PlatformViewAppState(); +} + +class PlatformViewAppState extends State { + + Widget _getBannerWidget() { + // Test IDs from Admob: + // https://developers.google.com/admob/ios/test-ads + // https://developers.google.com/admob/android/test-ads + final String bannerId = Platform.isAndroid + ? 'ca-app-pub-3940256099942544/6300978111' + : 'ca-app-pub-3940256099942544/2934735716'; + final BannerAd bannerAd = BannerAd( + adUnitId: bannerId, + request: const AdRequest(), + size: AdSize.banner, + listener: const BannerAdListener(), + ); + bannerAd.load(); + return Align( + alignment: Alignment.bottomCenter, + // Use 320x50 Admob standard banner size. + child: SizedBox( + width: 320, + height: 50, + child: AdWidget(ad: bannerAd), + ), + ); + } + + @override + Widget build(BuildContext context) { + return MaterialApp( + theme: ThemeData.light(), + title: 'Advanced Layout', + home: Scaffold( + appBar: AppBar(title: const Text('Platform View Bottom Ad Banner')), + body: Column( + children: [ + Expanded( + child: ListView.builder( + key: const Key('platform-views-scroll'), // This key is used by the driver test. + itemCount: 250, + itemBuilder: (BuildContext context, int index) { + return const Card( + elevation: 2, + child: ListTile( + title: Text('Breaking News!'), + subtitle: Text('Huge breaking news! Here is huge and breaking news which is both huge and breaking.'), + leading: FlutterLogo(), + ), + ); + }, + ), + ), + _getBannerWidget(), + ] + ) + ), + ); + } +} diff --git a/dev/benchmarks/platform_views_layout/test_driver/scroll_perf_bottom_ad_banner_test.dart b/dev/benchmarks/platform_views_layout/test_driver/scroll_perf_bottom_ad_banner_test.dart new file mode 100644 index 0000000000000..ccac5ab8dcc3e --- /dev/null +++ b/dev/benchmarks/platform_views_layout/test_driver/scroll_perf_bottom_ad_banner_test.dart @@ -0,0 +1,59 @@ +// Copyright 2014 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter_driver/flutter_driver.dart'; +import 'package:test/test.dart' hide TypeMatcher, isInstanceOf; + +void main() { + group('scrolling performance test', () { + late FlutterDriver driver; + + setUpAll(() async { + driver = await FlutterDriver.connect(); + + await driver.waitUntilFirstFrameRasterized(); + }); + + tearDownAll(() async { + driver.close(); + }); + + Future testScrollPerf(String listKey, String summaryName) async { + // The slight initial delay avoids starting the timing during a + // period of increased load on the device. Without this delay, the + // benchmark has greater noise. + // See: https://github.com/flutter/flutter/issues/19434 + await Future.delayed(const Duration(milliseconds: 250)); + + final Timeline timeline = await driver.traceAction(() async { + // Find the scrollable stock list + final SerializableFinder list = find.byValueKey(listKey); + + for (int j = 0; j < 5; j += 1) { + // Scroll down + for (int i = 0; i < 5; i += 1) { + await driver.scroll(list, 0.0, -300.0, const Duration(milliseconds: 300)); + await Future.delayed(const Duration(milliseconds: 500)); + } + + // Scroll up + for (int i = 0; i < 5; i += 1) { + await driver.scroll(list, 0.0, 300.0, const Duration(milliseconds: 300)); + await Future.delayed(const Duration(milliseconds: 500)); + } + } + }); + + final TimelineSummary summary = TimelineSummary.summarize(timeline); + await summary.writeTimelineToFile(summaryName, pretty: true); + } + + test('platform_views_scroll_perf', () async { + // Disable frame sync, since there are ongoing animations. + await driver.runUnsynchronized(() async { + await testScrollPerf('platform-views-scroll', 'platform_views_scroll_perf_bottom_ad_banner'); + }); + }, timeout: Timeout.none); + }); +} diff --git a/dev/benchmarks/platform_views_layout/test_driver/uikit_view_scroll_perf_bottom_ad_banner.dart b/dev/benchmarks/platform_views_layout/test_driver/uikit_view_scroll_perf_bottom_ad_banner.dart new file mode 100644 index 0000000000000..c7661675c0583 --- /dev/null +++ b/dev/benchmarks/platform_views_layout/test_driver/uikit_view_scroll_perf_bottom_ad_banner.dart @@ -0,0 +1,13 @@ +// Copyright 2014 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/widgets.dart'; +import 'package:flutter_driver/driver_extension.dart'; + +import 'package:platform_views_layout/main_bottom_ad_banner.dart' as app; + +void main() { + enableFlutterDriverExtension(); + runApp(const app.PlatformViewApp()); +} diff --git a/dev/devicelab/bin/tasks/platform_views_scroll_perf_bottom_ad_banner__timeline_summary.dart b/dev/devicelab/bin/tasks/platform_views_scroll_perf_bottom_ad_banner__timeline_summary.dart new file mode 100644 index 0000000000000..d0fb210c39bac --- /dev/null +++ b/dev/devicelab/bin/tasks/platform_views_scroll_perf_bottom_ad_banner__timeline_summary.dart @@ -0,0 +1,12 @@ +// Copyright 2014 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter_devicelab/framework/devices.dart'; +import 'package:flutter_devicelab/framework/framework.dart'; +import 'package:flutter_devicelab/tasks/perf_tests.dart'; + +Future main() async { + deviceOperatingSystem = DeviceOperatingSystem.ios; + await task(createUiKitViewScrollPerfBottomAdBannerTest(enableImpeller: true)); +} diff --git a/dev/devicelab/lib/tasks/perf_tests.dart b/dev/devicelab/lib/tasks/perf_tests.dart index bb92600ddfbf4..661c52a71524a 100644 --- a/dev/devicelab/lib/tasks/perf_tests.dart +++ b/dev/devicelab/lib/tasks/perf_tests.dart @@ -74,6 +74,17 @@ TaskFunction createUiKitViewScrollPerfAdBannersTest({bool? enableImpeller}) { ).run; } +TaskFunction createUiKitViewScrollPerfBottomAdBannerTest({bool? enableImpeller}) { + return PerfTest( + '${flutterDirectory.path}/dev/benchmarks/platform_views_layout', + 'test_driver/uikit_view_scroll_perf_bottom_ad_banner.dart', + 'platform_views_scroll_perf_bottom_ad_banner', + testDriver: 'test_driver/scroll_perf_bottom_ad_banner_test.dart', + needsFullTimeline: false, + enableImpeller: enableImpeller, + ).run; +} + TaskFunction createUiKitViewScrollPerfNonIntersectingTest({bool? enableImpeller}) { return PerfTest( '${flutterDirectory.path}/dev/benchmarks/platform_views_layout',