Top 5 tips for flutter performance optimization and following best practices to build your next project.
Ever thought of why your app faces lag/jank on some devices. Let’s get into some key points to improve user experience and performance of your app. This story will focus on some basic and advanced tips to boost your app. So, without wasting any time let’s get started with our first point.
1) Handling Image dimensions to reduce jank
Thinking to build next e-commerce app or social media app which requires a lot of image data? Then you might be performing some wrong techniques. Let’s get into some, most of the time you might be picking images by following way.
final XFile? imageFile= await picker.pickImage(
source: ImageSource.gallery,
);
But the above method is incomplete as you should always specify maxWidth and maxHeight attribute while picking the image. The reason behind it is that when you pick an image without these attributes than the image picked might be of a large dimension (2400X1600) which is a very huge as compared to the average dimension of a mobile device i.e. 360X800. Which would eventually lead to jank when such a network image is loaded as the task of compressing the original image to the required size of display is heavy. So, its better if you provide maxWidth to automatically resize the image while picking, this will not only save us from experiencing the jank but will also reduce the volume of image. Thus lesser time to load such a network image and increasing the performance while rendering image.
Let’s take an example of a responsive web where 3 images (each of 500X650) are shown in a row and when the web is loaded on a mobile device then dimension of each image is nearly reduced to 150X200 then based on your needs you need to find a average size for max dimensions of the picked image. Now, either you can take the average dimension of image for both the situations or if the difference between 2 situation is huge than you can have multiple images for the different dimensions. Therefore, for mobile the best way to pick image could be:-
final XFile? imageFile= await picker.pickImage(
maxWidth: 150,
maxHeight:
200,
source: ImageSource.gallery,
);
2) Handling image loading for better user experience
![]() |
BlurHash to show a blur preview image till it loads rather then showing grey boxes |
Now, since we have understood how to reduce jank and handle such images now it’s time to load the images in a better way to smoothen the user experience. Most of the time you might be showing a grey colored or any color box, or maybe a progress indicator while the network image is loaded which looks too shabby on your wonderful UI. To solve this problem and optimize your app BlurHash comes into play. So, what is blurhash? BlurHash takes an image, and give a short string (only 20–30 characters!) that represents the placeholder for this image i.e. while the image is loaded you can show the blur preview of the image using the generated string rather than showing a grey box or progress indicator.
To generate this string you need to add
blurhash: ^1.0.0
plugin in your pubspec.yaml file and when you are uploading the image to
firebase or any database then call the below function:-
Future<String> blurHashEncode(File file) async {
Uint8List pixels = file.readAsBytesSync();
String result = await blur.BlurHash.encode(pixels, 4, 3);
return result;
}
This will return the blur hash encoded string which you can store in your database along with the image url. Therefore the final upload function would look like:-
Now, it’s time to display the image for which we need to add
octo_image: ^1.0.1
plugin which will provide the placeholder accepting our encoded string. So
to display the image our image widget would look like this:-
3) Use AspectRatio for showing images
Ever wondered how to tell exact dimensions of an image to upload in your app? or while making an app you might be hardcoding image length and width to obtain it which is among the bad practices. Let’s understand the problem of doing it. So, if you display image based on the device height and width i.e by using MediaQuery as you won’t get the exact image dimensions to upload as size of various device differs so you may end up using BoxFits to cover the whole space which may end up cropping some essential details of the image. Now you might be thinking to set height and width as pixels i.e. an image widget of width and height as 200X150. Though you will get the dimensions for the image but as pixel density differs in devices the UI maybe odd for some devices.
So, the best possible way is to use AspectRatio. So what is aspect ratio? It is the ratio of length of image to the width i.e. if you want to show an image of dimension 200X150 then your aspect ratio is 200/150 i.e. ~1.33. So, wrap your image widget with AspectRatio and provide aspectRatio for it and even some widgets like CarouselSlider already have aspectRatio as their parameter so you don’t need to wrap them in another widget. The benefit would be that image details won’t be clipped and uniformity in displaying image on all devices because even if the pixel density is different for various devices it will automatically enlarge or reduce the size of image to match your UI i.e. you don’t need to hardcode the length and width of image in pixels. Boom! Now you can inform the admin of the e-commerce app to upload image of their product in specified aspect ratio(~1.33) or dimension(200X150). Therefore the above example to display image along with aspect ratio would look like:-
4) Proper disposal of controllers
Most of the time people tend to dispose of the controllers like TextEditingController, AnimationController etc. after calling super.dispose() i.e. somewhat as shown below:-
So what exactly happens when you try to dispose them after calling super.dispose() is that the resources occupied are not freed. As in official docs :-
Implementations of dispose method should end with a call to the
inherited method, as in
super.dispose()
.
So, the best way to dispose is before calling super.dispose() as anything you dispose after it is useless.
5) Showing different widgets based on conditions (Avoid else)
Suppose you are making an app with chat functionality or notification then you might be showing different types of notification or messages in a different way. For example you are classifying different messages of a chat app based on 3 types i.e. text message, image message and video message. So for each message you might be showing different message box i.e. your widget function might look like the below one:-
But there’s a huge flaw in this approach. Suppose in future you wish to add an update in your app where you add another messageType as pdfFile then the app might crash for the users who are using the old version of app as for them the imageWidget will be returned for this new message as well. The reason for crash is that the imageWidget will try to show the image by url but this new message contains the url of a file not an image. So next time use the following way to show different widgets.
Conclusion
Congrats!! Now you have learnt some of the best practices to be used in
your upcoming project.
And ya do lemme know your views on this
story and do you want to have such more stories or you want on some other
topic?
Comments
Post a Comment