Irbisa · Шпаргалка
Производительность
Конвейер рендеринга, jank, утечки памяти, инструменты профилирования
Как сократить лишние ребилды виджетов (
const, мелкие виджеты,select)?// before: one counter rebuilds the whole page on every tapclass _CatalogPageState extends State<CatalogPage> { int _count = 0; @override Widget build(BuildContext context) => Column(children: […Чем ребилд отличается от перерисовки (repaint) и что на самом деле делает
RepaintBoundary?import 'package:flutter/rendering.dart'; void main() { // Debug only: a layer's border changes colour every time it repaints debugRepaintRainbowEnabled = true; runApp(const MyApp());…Как профилировать Flutter-приложение и что показывают столбики UI и raster в DevTools?
ListViewна тысячи элементов тормозит при скролле. Как сделать длинный список плавным?class FeedList extends StatelessWidget { const FeedList({super.key, required this.posts}); final List<Post> posts; @override Widget build(BuildContext context) {…Найдите баг: этот список заказов теряет кадры при каждом флинге, хотя построен на
ListView.builder.class OrdersList extends StatelessWidget { const OrdersList({super.key, required this.orders, required this.query}); final List<Order> orders; // about 5,000 orders final String query; @override Widget build(BuildContext context) => ListView.builder( itemCount: orders.where((o) => o.title.contains(query)).length, itemBuilder: (context, i) { final visible = orders.where((o) => o.title.contains(query)).toList() ..sort((a, b) => b.date.compareTo(a.date)); return OrderTile(order: visible[i]); }, );}Этот спиннер заставляет всю страницу перестраиваться 60 раз в секунду. Почему и как сузить анимацию?
class _SyncPageState extends State<SyncPage> with SingleTickerProviderStateMixin { late final _ctrl = AnimationController( vsync: this, duration: const Duration(seconds: 1)) ..addListener(() => setState(() {})) ..repeat(); @override Widget build(BuildContext context) => Column(children: [ Transform.rotate( angle: _ctrl.value * 2 * pi, child: const Icon(Icons.sync), ), Expanded(child: HeavyReport(rows: widget.rows)), ]);}Этот график перерисовывается при каждом ребилде родителя, хотя его данные не меняются. Что не так?
class ChartPainter extends CustomPainter { ChartPainter(this.points); final List<double> points; @override void paint(Canvas canvas, Size size) { // draws a polyline through points } @override bool shouldRepaint(ChartPainter oldDelegate) => true;} // In the parent's build():CustomPaint(painter: ChartPainter(state.points.toList()))Почему
Opacity,BackdropFilterи клипы со сглаживанием дорогие и чем их заменить?// before: an offscreen layer just to dim one labelOpacity(opacity: 0.5, child: Text('Archived')) // after: the alpha is part of the paint, no extra layerText( 'Archived',…Что такое Impeller, почему он заменил Skia и что стало с прогревом шейдеров?
Что такое tree shaking в release-сборке Flutter и почему его может сломать неконстантный
IconData?// wrong: the glyph is chosen at runtime, so the font cannot be tree shakenIcon(IconData(category.codePoint, fontFamily: 'MaterialIcons')) // right: every glyph is a compile-time constantconst categoryIcons = <String, IconData>{ 'food': Icons.restaurant,…При переходе на экран деталей теряются кадры в первой части анимации. Что происходит и как это исправить?
Что вызывает jank во Flutter и как подходить к его устранению в реальном приложении?
Как найти и устранить утечки памяти во Flutter-приложении?
class _ChatState extends State<ChatScreen> { final _input = TextEditingController(); final _scroll = ScrollController(); StreamSubscription<Message>? _sub; Timer? _typing;…Как ускорить холодный старт и почему приложение часто медленное только при первом запуске?
Future<void> main() async { WidgetsFlutterBinding.ensureInitialized(); // Only what the first screen cannot render without final prefs = await SharedPreferences.getInstance(); runApp(App(prefs: prefs));…Приложение весит 90 МБ, продукт хочет вдвое меньше. Как найти, что занимает место, и урезать?
# Size report per package, library and asset (open the JSON in DevTools > App Size)flutter build appbundle --release --analyze-size --target-platform android-arm64flutter build ipa --release --analyze-size # Smaller binary: symbols move out; keep them for crash symbolicationflutter build appbundle --release \…DevTools показывает Dart-кучу на 40 МБ, а ОС показывает 500 МБ и убивает приложение в фоне. Где память?
На вашем телефоне приложение плавное. Как мониторить его производительность у реальных пользователей?
void startFrameMonitoring(void Function(Map<String, double>) report) { final buildMs = <double>[]; final rasterMs = <double>[]; SchedulerBinding.instance.addTimingsCallback((List<FrameTiming> timings) { for (final t in timings) {…Как не дать регрессии времени кадра попасть в main, а не узнавать о ней после релиза?
// integration_test/scroll_perf_test.dartvoid main() { final binding = IntegrationTestWidgetsFlutterBinding.ensureInitialized(); testWidgets('feed scrolls within budget', (tester) async { await tester.pumpWidget(const App()); await tester.pumpAndSettle();…