Skip to content

screen rebuilds when using coordinator (resolved, open issue for reference only) #10

@YuryMorozov2001

Description

@YuryMorozov2001

Hi! Thanks for this amazing package and the great work you’ve done!
I noticed that when using coordinator.push/pop, screens are being rebuilt even when its not necessary. Maybe we should use caching. Do you have any ideas on how we can fix this?

2025-12-07.21.00.07.mov

To detect which widgets are being rebuilt, I used this code

2025-12-07.21.02.10.mov

Also, if the widget in the router is declared as const, there are no unnecessary rebuilds:

2025-12-07.21.16.11.mov
Demo code
import 'package:flutter/material.dart';
import 'package:routing/flutter_scan.dart';
import 'package:zenrouter/zenrouter.dart';

void main() {
  runApp(const MainApp());
}

final appCoordinator = AppCoordinator();

class MainApp extends StatelessWidget {
  const MainApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp.router(
      routerDelegate: appCoordinator.routerDelegate,
      routeInformationParser: appCoordinator.routeInformationParser,
    );
  }
}

abstract class AppRoute extends RouteTarget with RouteUnique {}

class AppCoordinator extends Coordinator<AppRoute> {
  @override
  AppRoute parseRouteFromUri(Uri uri) {
    return switch (uri.pathSegments) {
      [] => HomeRoute(),
      ['profile', String userId] => ProfileRoute(userId),
      _ => NotFoundRoute(),
    };
  }
}

class NotFoundRoute extends AppRoute {
  @override
  Uri toUri() => Uri.parse('/not-found');

  @override
  Widget build(Coordinator<AppRoute> coordinator, BuildContext context) {
    return Scaffold(body: Center(child: Text('Not found')));
  }
}

class NotFoundPage {}

class HomeRoute extends AppRoute {
  @override
  Uri toUri() => Uri.parse('/');

  @override
  Widget build(AppCoordinator coordinator, BuildContext context) {
    return HomeScreen();
    // return const HomeScreen();
  }
}

class ProfileRoute extends AppRoute {
  ProfileRoute(this.userId);
  final String userId;

  @override
  List<Object?> get props => [userId];

  @override
  Uri toUri() => Uri.parse('/profile/$userId');

  @override
  Widget build(AppCoordinator coordinator, BuildContext context) {
    return ProfilePage(userId: userId);
  }
}

class HomeScreen extends StatelessWidget {
  const HomeScreen({super.key});
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            Text('Home Page'),
            Text(DateTime.now().toString()),
            Builder(
              builder: (context) {
                return TextButton(
                  onPressed: () {
                    appCoordinator.push(ProfileRoute('123'));
                  },
                  child: Text('Go to profile'),
                );
              },
            ),
          ],
        ),
      ),
    );
  }
}

class ProfilePage extends StatelessWidget {
  const ProfilePage({super.key, required this.userId});

  final String userId;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisSize: .min,
          children: [
            Text('User ID: $userId'),
            TextButton(
              onPressed: () {
                Navigator.pop(context);
              },
              child: Text('back'),
            ),
          ],
        ),
      ),
    );
  }
}  

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions