-
Notifications
You must be signed in to change notification settings - Fork 29.8k
Description
When using MaterialRoute or MaterialPage on web or desktop, there's a 300ms delay when navigating back from any page. This makes Flutter apps on web and desktop very laggy:
PR #82596 removed the default animations from web and desktop, but didn't remove the animation transition delay, which is hard coded in MaterialRouteTransitionMixin. The navigator waits for the 300ms transitionDuration before popping the page. This change is in the current beta branch 2.5.0-5.1.pre.
I feel this change should be reverted until there's a solution for the delay: it's better to have an animation rather than a pause that will make developers feel something is broken. It especially feels laggy on web when using the browser's back button.
The hard-coding of the 300ms duration is really problematic; it also means the transition animation is incorrect on iOS (issue #80929). Ideally the transition duration would be provided in the transition themes.
Related issue that users are likely to run into when trying to remove this delay:
Example app code
import 'dart:async';
import 'package:flutter/material.dart';
void main() {
runApp(MaterialApp(home: PageOne()));
}
class PageOne extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Page one'),
),
body: Center(
child: ElevatedButton(
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute(builder: (_) => PageTwo()),
);
},
child: const Text('Push page two'),
),
),
);
}
}
class PageTwo extends StatefulWidget {
@override
_PageTwoState createState() => _PageTwoState();
}
class _PageTwoState extends State<PageTwo> {
final _timer = NotifyingTimer();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
leading: BackButton(
onPressed: () {
_timer.go();
Navigator.pop(context);
},
),
title: AnimatedBuilder(
animation: _timer,
builder: (_, __) => Text('${_timer.stopwatch.elapsedMilliseconds}ms'),
),
),
);
}
}
class NotifyingTimer extends ChangeNotifier {
final stopwatch = Stopwatch();
void go() {
stopwatch.start();
Timer.periodic(
const Duration(milliseconds: 1),
(_) => notifyListeners(),
);
}
}