Repository navigation
Open
Labels
P3Issues that are less important to the Flutter projectIssues that are less important to the Flutter projectc: new featureNothing broken; request for a new capabilityNothing broken; request for a new capabilityc: proposalA detailed proposal for a change to FlutterA detailed proposal for a change to Flutterd: api docsIssues with https://api.flutter.dev/Issues with https://api.flutter.dev/d: examplesSample code and demosSample code and demosf: integration_testThe flutter/packages/integration_test pluginThe flutter/packages/integration_test pluginframeworkflutter/packages/flutter repository. See also f: labels.flutter/packages/flutter repository. See also f: labels.platform-webWeb applications specificallyWeb applications specificallyteam-webOwned by Web platform teamOwned by Web platform teamtriaged-webTriaged by Web platform teamTriaged by Web platform team
Description
Use case
Hi!
We're trying to write down an automated way to measure RAM usage of our applications on Flutter Web.
That way should be an integration test, but as the documentation says:
Recording performance timelines isn't supported on web. For performance profiling on web, see Debugging performance for web apps
... And the latter link redirects to a page that shows how to profile a web app. But that's not programmatic!
Proposal
Let this code work, even on Flutter Web:
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
void main() {
final binding = IntegrationTestWidgetsFlutterBinding.ensureInitialized();
testWidgets('Counter increments smoke test', (tester) async {
// Build our app and trigger a frame.
await tester.pumpWidget(
MyApp(items: List<String>.generate(10_000, (i) => 'Item $i')),
);
final listFinder = find.byType(Scrollable);
final itemFinder = find.byKey(const ValueKey('item_500_text'));
await binding.traceAction(() async {
await tester.scrollUntilVisible(
itemFinder,
500.0,
scrollable: listFinder,
);
}, reportKey: 'scrolling_timeline');
});
}
class MyApp extends StatelessWidget {
final List<String> items;
const MyApp({super.key, required this.items});
@override
Widget build(BuildContext context) {
const title = 'Long List';
return MaterialApp(
title: title,
home: Scaffold(
appBar: AppBar(title: const Text(title)),
body: ListView.builder(
key: const Key('long_list'),
itemCount: items.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(
key: Key('item_${index}_text'),
items[index],
),
);
},
),
),
);
}
}or, in other words, make this cookbook available for Flutter Web users, as well.
Metadata
Metadata
Assignees
Labels
P3Issues that are less important to the Flutter projectIssues that are less important to the Flutter projectc: new featureNothing broken; request for a new capabilityNothing broken; request for a new capabilityc: proposalA detailed proposal for a change to FlutterA detailed proposal for a change to Flutterd: api docsIssues with https://api.flutter.dev/Issues with https://api.flutter.dev/d: examplesSample code and demosSample code and demosf: integration_testThe flutter/packages/integration_test pluginThe flutter/packages/integration_test pluginframeworkflutter/packages/flutter repository. See also f: labels.flutter/packages/flutter repository. See also f: labels.platform-webWeb applications specificallyWeb applications specificallyteam-webOwned by Web platform teamOwned by Web platform teamtriaged-webTriaged by Web platform teamTriaged by Web platform team
Activity
ladlaladka681-ops commentedon Jan 11, 2026
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
void main() {
final binding = IntegrationTestWidgetsFlutterBinding.ensureInitialized();
testWidgets('Counter increments smoke test', (tester) async {
// Build our app and trigger a frame.
await tester.pumpWidget(
MyApp(items: List.generate(10_000, (i) => 'Item $i')),
);
});
}
class MyApp extends StatelessWidget {
final List items;
const MyApp({super.key, required this.items});
@OverRide
Widget build(BuildContext context) {
const title = 'Long List';
}
}
justinmc commentedon Jan 13, 2026
@mdebbar Passing this to team-web, but let me know if it's more our thing.
yjbanov commentedon Jan 14, 2026
traceActiondoes not measure RAM usage. How do you propose RAM usage is extracted? It's also not clear how to attribute RAM usage to the scope of onetraceAction. Objects in memory can come from inside as well as outside the scope oftraceAction.Have you considered writing a
FlutterDrivertest instead of the integration test? This way you can connect to the browser's debug protocol and extract performance data. I believe Chrome debug protocol supports extracting memory usage as well.lucavenir commentedon Jan 14, 2026
yes, I realized this only afterwards; but because of #180690 (comment), now I need benchmark performance in general (and not just RAM) to evaluate if introducing WASM is worth the trade.
I have no clue, but in desperation, I made something:
Although I'm kinda lost in the fog. I'm not sure this is idiomatic or if it'll work at least decently to benchmark my application.
yes, that's the above snippet; the point is that:
lucavenir commentedon Jan 16, 2026
UPDATE; RE; memory usage. commenting here since "performance" (imho) also includes memory usage, and it could be useful to some.
turns out
window.performance.memory, while fully adopted by all browsers, is deprecated and might be unreliable.therefore, as mentioned by the mdn docs, we should use this API; however, it is marked as experimental and it requires cross-origin isolation (that's been fixed in master, see #180690 (comment)).
by the way, this is exactly what the devtools are doing, I'd just love to do this programmatically in my own code - I guess borrowing a few LoC from the devtools is not that big of a deal.
mdebbar commentedon Jan 21, 2026
Thanks for the proposal!
I did some research online and found the same info that you found: the deprecated
performance.memoryand the newmeasureUserAgentSpecificMemoryAPI. The latter has limited availability, but that may not matter if you run your tests in Chrome/Firefox (both have supported this API for a while).Unfortunately, we currently don't have plans to work on this, but I'll leave this issue open for tracking in case our plans change in the future.
lucavenir commentedon Jan 21, 2026
I want to remark - Iin case anyone needs this: invoking
.measureUserAgentSpecificMemoryis totally doable on a cross-origin isolated chrome session, that works withflutter driverand that's reliable.