Improving perceived performance with image placeholders, precaching, and disabled navigation…

Improving perceived performance with image placeholders, precaching, and disabled navigation transitions Perceived performance is how fast an application feels to the user. This article covers three strategies that you can use in your application to improve perceived performance: image placeholders, precaching images, and disabling navigation transitions. Image placeholders to prevent content from jumping around When a user is waiting for images to load, and then they eventually show up, the layout can shift around. By leaving space in the layout for image placeholders, you can avoid this shifting to ensure a better user experience. See the following GIF for an example of how it can look without using any placeholders: See full interactive example on DartPad. If you already have a placeholder image cached and loaded in your application you can use the FadeInImage widget to show placeholders. If you want to use a widget instead of an image as a placeholder, you can achieve this with the Image.frameBuiler property. The Image.frameBuilder property is responsible for building the Image widget and it has four arguments: The build context. The image widget child. A number representing the frame, which is null when the image is still loading. A boolean wasSynchronouslyLoaded that is true if the image is already loaded. When implementing a placeholder widget, first check whether the image has already been loaded with wasSynchronouslyLoaded and, if so, return the child. If not, use AnimatedSwitcher to create a cross-fade between the placeholder and the image as it loads: class ImageWidgetPlaceholder extends StatelessWidget { const ImageWidgetPlaceholder({ Key key, this.image, this.placeholder, }) : super(key: key); final ImageProvider image; final Widget placeholder; @override Widget build(BuildContext context) { return Image( image: image, frameBuilder: (context, child, frame, wasSynchronouslyLoaded) { if (wasSynchronouslyLoaded) { return child; } else { return AnimatedSwitcher( duration: const Duration(milliseconds: 500), child: frame != null ? child : placeholder, ); } }, ); } } After adding placeholders, the layout no longer shifts around, and instead the images fade in as they load: See full interactive example on DartPad. Precaching images before they are displayed If your app has a splash or welcome screen before images are shown, you can also precache those images by calling the precacheImage function. precacheImage(NetworkImage(url), context); The following GIF shows an example of precaching images on a Welcome screen: See full interactive example on DartPad. Disabling navigation transitions on Flutter web Navigation transitions occur when a user moves between pages, and it can be a great way to let the user orient themselves in a mobile application. However, for web applications, it’s not something you would typically see. For a perceived performance improvement, you can disable the page transition animation. By default, MaterialApp uses page transitions for routing relevant to the platform (slide in upwards for Android or from the side for iOS). To override this behavior, you can create your own PageTransitionsTheme class. To detect when the application runs on the web, use the kIsWeb constant. If it is on the web, disable the transition by returning the child: import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; class NoTransitionsOnWeb extends PageTransitionsTheme { @override Widget buildTransitions<T>( route, context, animation, secondaryAnimation, child, ) { if (kIsWeb) { return child; } return super.buildTransitions( route, context, animation, secondaryAnimation, child, ); } } Set the pageTransitionsTheme for our MaterialApp: MaterialApp( theme: ThemeData( pageTransitionsTheme: NoTransitionsOnWeb(), ), ) The page transition without any animation: See full interactive example on DartPad. Conclusion I hope you found some useful tips in this article for how to improve the perceived performance in an application. This post is a part of a series about what we learned when improving performance for the Flutter Gallery . For the Flutter Gallery , we disabled the page transitions on the web and added placeholders for images to avoid a layout shift while loading. The implementation is similar to what is described in this article, and if you want to see the code you can find it on GitHub . Thank you for reading! Improving perceived performance with image placeholders, precaching, and disabled navigation… was originally published in Flutter on Medium, where people are continuing the conversation by highlighting and responding to this story.