-
Notifications
You must be signed in to change notification settings - Fork 30.1k
Description
Hello,
Currently we developing a Flutter Web application with the intent to move to production in a few months. Almost everything works great but we found a major performance issue when subscribing to mouse events for many widgets.
We use ListView to display/scroll grid-like data and scrolling performance is 60fps on our testing devices which is perfect for us. But when we attach mouse event listeners to our widgets/cells we get major performance regression. (we tried to show tooltips using Tooltip widget but the problem seems to be much wider).
We found that this issue somewhat relates to widgets having rounded borders and/or different borders specified for each side. The problem should be easily reproducible so we provide only minimal main.dart examples without videos.
Scrolling in both examples below produces less than 60fps, but if you comment onEnter: (_) => {} handler in MouseRegion performance will increase dramatically and will reach 60fps.
main.dart: Case 1: Border radius
import 'package:flutter/material.dart';
Future<void> main() async {
runApp(MyApp());
}
@immutable
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
const int rowsCount = 60;
const int columnsCount = 20;
const double containerSize = 40;
return MaterialApp(
home: Scaffold(
body: ListView.builder(
itemCount: rowsCount,
cacheExtent: rowsCount * containerSize,
itemBuilder: (BuildContext context, _) => Row(
children: List<Widget>.generate(
columnsCount,
(_) => MouseRegion(
// Comment the line below to fix the performance problem
onEnter: (_) => {},
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
border: Border.all(
width: 1,
color: Colors.lightBlue,
),
),
width: containerSize,
height: containerSize,
),
),
),
),
)),
);
}
}main.dart: Case 1: Different side borders
import 'package:flutter/material.dart';
Future<void> main() async {
runApp(MyApp());
}
@immutable
class MyApp extends StatelessWidget {
Border _getBorder(int columnIndex, int rowIndex) {
const BorderSide defaultBorderSide = BorderSide();
return Border(
left: columnIndex == 0 ? defaultBorderSide : BorderSide.none,
top: rowIndex == 0 ? defaultBorderSide : BorderSide.none,
right: defaultBorderSide,
bottom: defaultBorderSide,
);
}
@override
Widget build(BuildContext context) {
const int rowsCount = 60;
const int columnsCount = 20;
const double containerSize = 50;
return MaterialApp(
home: Scaffold(
body: ListView.builder(
itemCount: rowsCount,
cacheExtent: rowsCount * containerSize,
itemBuilder: (BuildContext context, int rowIndex) => Row(
children: List<Widget>.generate(
columnsCount,
(int columnIndex) => MouseRegion(
// Comment the line below to fix the performance problem
onEnter: (_) => {},
child: Container(
decoration: BoxDecoration(
border: _getBorder(columnIndex, rowIndex),
),
width: containerSize,
height: containerSize,
),
),
),
),
)),
);
}
}We also found that the issue does not appear if we enable Skia based renderer so its source might be in Flutter Web engine, not in framework.
Please let me know if you need any additional information (videos, profile snapshot, etc) to diagnose the issue.
We wonder if there any existing issues/plans to improve Flutter Web performance in such scenarios, or is there any workaround for this?...
Doctor summary (to see all details, run flutter doctor -v):
[√] Flutter (Channel unknown, v1.10.6-pre.7, on Microsoft Windows [Version 10.0.17134.950], locale ru-RU)
[√] Android toolchain - develop for Android devices (Android SDK version 28.0.3)
[√] Chrome - develop for the web
[√] Visual Studio - develop for Windows (Visual Studio CommunityВ 2019 16.3.0)
[√] Android Studio (version 3.5)
[√] VS Code (version 1.38.1)
[√] Connected device (3 available)
• No issues found!