I am looking for some practices to follow for making my startup's app performant.
Please share the tips/tricks and practices that you follow for making Flutter apps smoother. I have shared some practices that I currently follow. Thank you!
Flutter apps are very performant if some of the performance optimisations are kept in mind while developing the apps. No doubt, apps can become laggy and janky.
1: Use smaller image files:
No doubt, images are essential for any mobile application. And this is the area where performance gets the hit by a good margin, if not managed correctly. I started my journey as an Android Developer and I soon experienced lot of lag and poor performance in my apps. Later, I found that I was using the images which were of several MBs each. The resolution of image assets was much higher than required.
This took lot of time for device to load the assets and draw pixels, increasing CPU & GPU’s work. Sometimes, images even failed to load, making app completely unresponsive.
Here are some tips to follow to avoid performance issues related to image assets.
Try reducing size of you images from tinypng.
Lower the resolution of image here. Make sure the resolution is not more than any higher end device’s resolution.
2: Avoid Unnecessary Animations
Animation is a foe of performance, using animations may cause your device resources to constantly work (since the animation values are generated again & again). CPU constantly needs to generate values & GPU has to redraw widgets.
3: Remove Redundant Widgets
Personally, I used lot of redundant widgets like useless containers & other widgets which did not contribute to overall UI feel of the app. Gradually, I realised that this was becoming my habit. Although this can be subjective. Make sure to use only those widgets which are necessary.
4: Proper State Management
A proper state management solution can make your app very efficient & avoid computational overhead. A typical Flutter app may contain hundreds of widgets. Updating these widgets & redrawing them again & again may cause your device to work more. The proper state management allows only necessary widgets to update their state or redraw. Let’s assume that you are using Provider as your state management tool for the app, Provider will only notify its listeners i.e consumer widgets. Only widgets listening to that Change Notifier Provider will update.
Image description
5: Use Dart Dev Tools (Flutter Dev Tools)
Dart Dev Tools is a combination of some useful profiling tools which can help to determine which widget or functionality is taking much processing power and cause lag or jank. Dev Tools illustrate a clear picture of things happening at main & UI thread.
Image description
6: Use Const Widgets Wherever Possible
It is good practice to use the keyword const for constants that we can initialise at compile time. Let's also not forget to use const as much as possible for our widgets, this allows us to catch and reuse widgets to avoid unnecessary rebuilds that are caused by their ancestors.
7: Avoid Functional Components
Flutter is all about widgets, creating a custom widget can be done in two popular ways. Either create a function returning respective widget (functional approach) or create a whole new widget. It is highly recommended to create either Stateless or Stateful widget rather than creating a function.
Related
I'm investigating integrating Flutter into existing iOS and Android projects. My main experience is in iOS, so this post will be from an iOS perspective. But feel free to substitute UIViewController for Activity/Fragment. I'll give some background on my current understanding, and will have my actual questions at the end of the post.
Our main use case is to embed small Widgets into existing view controllers. I've gone through the Flutter docs and guides and have successfully integrated with our project (it was actually pretty easy!) but have concerns with Flutter's overall design being incompatible with our desired usage.
It seems that Flutter would ideally like to be the entire UI for an application: create and start an engine on app launch, pass the engine to a FlutterView, and make that the root view for the app. Alternatively, Flutter seems happy to own whole flows in the app where you push a fullscreen Widget which does some work, maybe pushes/pops more screens, and eventually returns control back to the native app.
However, in the case where I have a native screen with some UI components where I want to also have a flutter Widget which displays some other data - e.g. a bar graph - it seems that I need to either create separate modules, or separate #pragma(vm:entry-point) functions in my Flutter project for each type of Widget (graph, in this case) that I'd like to display.
My understanding is that each of these Widgets would also need their own Flutter engine instance which loads the proper entry point/route to that Widget's main function which then calls runApp(MyWidget).
So on to my actual questions:
What are the best practices for embedding Flutter Widgets in view controllers?
Is this correct that to have a set of small Widgets that are embedded into a view controller, I'll need to create separate engine isolates for each one?
Is this even the right way to think about using Flutter? I know there are workarounds for engine startup latency with pre-warming and caching, and I could recreate the whole screen in Flutter. But I would like to preserve our native work where I can and have Flutter be an additive change.
Can engines be efficiently reused for separate vm entry points? Would it be "weird" to have a pool of cached engines that can be used on-demand (aside from memory pressure and thread limits)?
I'm still wrapping my head around Flutter, but I've been impressed with its capabilities so far! Please let me know if I'm missing something here.
For anyone coming across this in the future, as of Oct. 21, 2020, the use case of embedding multiple Flutter widgets inside of a native UIViewController is not encouraged. Doing this in a performant manner requires updates to Flutter to better share memory and threads across engine instances.
I have a very simple app which runs great on the PC, but runs 'acceptably' –not by much though- on my tablet (Samsung Galaxy Tab 3, SM-T210). It’s a very simple app so I thought that it would have ran great from day one, but it didn’t. I’ve seen some really resourceful applications –mine cannot even compare to them- running very fast and smoothly on a tablet. So I’ve been wondering how to accomplish that.
I’ve heard that you can accelerate your flex application using Stage3D, Starling or Feathers. I think with most frameworks I would have to rewrite part of my app because I would have to use the framework’s components to make the app run faster. I don’t know if I’m correct by this though. Is this correct?
Is there a way to accelerate my Flex Mobile app using one of those frameworks without having to rewrite a substantial part of my code? If so, can you tell me how?
Thanks in advance for your help.
Regards,
Sebastián
NEEDED FOR SOLUTION
Every tip that Rod stated is very important. It will improve the performance of a well-constructed application and make it run smoothly. The problem with those tips is that they are the smaller “half” of the iceberg and not the bigger “half”.
My application was transitioning very slowly from one View to another and this was due to the fact that I wasn’t “respecting” the Flex’s component Lifecycle. What I mean by this is that I was performing operations of configuration of the components after they were added to the DisplayList of the View and were validated. Also, I was adding children to the view programmatically after the method INITIALIZED event was fired. This made the View take more time to recalculate its children’s properties and add some more components to its DisplayList even after that part of the its lifecycle was supposed to be done. This made it take more time to render to its final state, hence, interrupting the transition from View to View. What I needed to do was to configure the components before they were added to the DisplayList and add more components to the View before createChildren() method was done.
The best and first advice, at least from my experience, to reach a “normal” performance is to abide by the guidelines of the lifecycle. Respect the construction, configuration, attachment and initialization parts of the process and you’ll be fine. If you don’t do this, all of the advices mentioned by Rod won’t be useful to get your application to perform smoothly.
It is true that only by abiding by the lifecycle you won’t be able to get your app to the best performance. For that, you’ll definitely need the advice mentioned before, but these tips are, what I call, the second part of the iceberg. First things first, code following the guidelines of the components’ lifecycle; second, follow all of Rod’s tips. With these two you’ll have a fast-as-lightening running app.
In my Flex-Mobile app, I haven't tried using any frameworks. In order to optimize my application, I am doing the following tips:
write item renderers on AS
subclass LabelItemRenderer or IconItemRenderer
avoid complex bindings
set autoDrawbackground to off
Use BitmapImage over Spark Image
use PNGs over JPEG or GIF. it takes less image decoding and rendering time
Text - Use StyleableTextfield (can be use only in AS)
write skins in AS (extend MobileSkin)
write custom component in AS3 not in MXML
setElementSize is cheaper than setting width and height
setElementPosition is cheaper than setting x and y properties
use light-weight components (i.e. Label)
use cacheAsBitmap property
components that are not changing frequently but are redrawn often
can be cached as Bitmap to optimize rendering time
don't use BorderContainer, use Group + Rect
reduce number of nested Groups
use Scroller.viewport instead of Scroller.verticalScrollbar
Do you have Lists in your app? You could rewrite ItemRenderers etc.
Every tip that Rod stated is very important. It will improve the performance of a well-constructed application and make it run smoothly. The problem with those tips is that they are the smaller “half” of the iceberg and not the bigger “half”.
My application was transitioning very slowly from one View to another and this was due to the fact that I wasn’t “respecting” the Flex’s component Lifecycle. What I mean by this is that I was performing operations of configuration of the components after they were added to the DisplayList of the View and were validated. Also, I was adding children to the view programmatically after the method INITIALIZED event was fired. This made the View take more time to recalculate its children’s properties and add some more components to its DisplayList even after that part of the its lifecycle was supposed to be done. This made it take more time to render to its final state, hence, interrupting the transition from View to View. What I needed to do was to configure the components before they were added to the DisplayList and add more components to the View before createChildren() method was done.
The best and first advice, at least from my experience, to reach a “normal” performance is to abide by the guidelines of the lifecycle. Respect the construction, configuration, attachment and initialization parts of the process and you’ll be fine. If you don’t do this, all of the advices mentioned by Rod won’t be useful to get your application to perform smoothly.
It is true that only by abiding by the lifecycle you won’t be able to get your app to the best performance. For that, you’ll definitely need the advice mentioned before, but these tips are, what I call, the second part of the iceberg. First things first, code following the guidelines of the components’ lifecycle; second, follow all of Rod’s tips. With these two you’ll have a fast-as-lightening running app.
I have a Gallery. This Gallery has a lot going on in it and it is slowing down the scrolling effect substantially. Does anyone have any idea as to how to optimize something like this?
The essence of my question is this: How can I make layouts that zip substantially faster than their standard android implementations. Renderscript? NDK? Flash layouts?
Keep in mind I am already caching my views. I know this is a very general question so any and all input is appreciated.
Thanks.
Quite often a sluggish UI is the result of doing a lot of work on the UI thread. I suppose you could double check whether this is the case and consider abstracting non-UI related logic into one or more different theads. E.g. you probably want to avoid fetching large amounts of resources from the SD card or a database on the UI thread. Doing such actions in seperate thread might improve responsiveness, although results will obviously depend on the particulars of your app.
Okay here is what I found from watching just the first several minutes of this video:
http://www.youtube.com/watch?v=v9S5EO7CLjo
I am building my app on 3.1. In the application tag of the Manifest, add the following as an attribute: android:hardwareAccelerated="true". The difference in UI performance is amazing. Thumbs up to Google for this addition to the Android SDK.
I am a complete noob to android but I have been programing c# for a long time. I am writing an android application and have gotten to a point where the c# programmer in me wants to start creating a loosely coupled design and and moving code into different layers, using interfaces, etc.
But then I stumble upon the Designing for performance guidelines it is telling me to avoid object creation and then it also is saying to optimize judicially.
Do I just build based on good design and then deal with performance issues as they come up?
The last thing I want to do is go through the work of building a application and have it perform poorly. Can someone point me to some examples of application that are designed well and have good performance or just make some recommendations?
Thanks
I've found AndEngine to be fairly well designed and it has to be concerned with performance since it is a game development library -- so you might pull down a copy of it and read the source.
In the "Designing for performance" document, I would point out this statement:
Note that although this document
primarily covers micro-optimizations,
these will almost never make or break
your software. Choosing the right
algorithms and data structures should
always be your priority, but is
outside the scope of this document.
An example of this would be creating a particle system. A good way to model it is to have a ParticleSystem object that holds a collection of Particle objects...maybe those Particles implement a Particle interface...this is not the place to avoid object creation. However, for performance reasons, you will want to optimize the ParticleSystem to recycle Particle objects rather than creating them from scratch every time you spawn one.
Personally, I haven't found performance to be much of a limiting factor but I suppose that will really depend on what type of app you're building.
My opinion is to build a suitable design first, test the performance, and optimize from there.
Pay more attention to Donald Knuth's quote that appear in the same article:
"We should forget about small
efficiencies, say about 97% of the
time: premature optimization is the
root of all evil.root of all evil."
Then if you are dealing with the other 3% you'll see...
As a general rule, the thing to do is keep the data structure as simple and normalized as you can. Like don't just throw in hash table data structures just because they are easy to grab. Know how to do profiling (here's my method) and if you have a real performance problem then fix it. Otherwise, the simpler the better, even if that means simple arrays, lists, and O(N) loops.
The reason to keep the data structure normalized is, if it is not, then it can have inconsistent states, and you will have a strong temptation to write notification-style code to try to keep it consistent. Those can be real performance killers. If you do those, the profiling will tell you it that's what is happening.
If you must have redundant data, I think it's better to be able to tolerate some temporary inconsistency, that you periodically repair by passing through the data. This is better than trying to intensely guarantee consistency at all times by notifications.
Another problem with unnormalized data structure is it can have lots of object creation and destruction. That also can be a real performance killer, although you can ameliorate it with the pool technique.
Are there pitfalls or the points to remember while programming for Android? I think the list will include topics on Multithreading, Persistent Storage, etc.
There are many things that could be said here.
The Android videos from Google I/O 2009 cover most of the aspects that should be kept in mind, when programming on Android. In fact, the http://android-developers.blogspot.com/ articles are the source, on which these presentations expand, and seeing them explained from some of the best Google engineers (and as a bonus you'll get a Q&A section) is a must for every Android developer, IMO.
Some of the things that could be mentioned:
Don't use floats, when you can achieve similar results with integers, because Android doesn't have native support for floating point values.
Use the debugging tools extensively, to optimize both performance and maintainability, and to avoid common pitfalls like ViewGroup redundancy in UI design, or unnecessary multiple calls to heavier methods (View.inflate(), findViewById(), setImageResource()).
Bundle your background service calls, otherwise you are waking up the OS unnecessarily and too often, while risking other services piggy-backing your call (which results in severely reduced battery life)
Prefer SAX-parsers over DOM-parsers, you lose time while implementing them, but you win time in your app's performance (and your device's availability)
Keep your UI manipulations on your UI thread, because the interface toolkit is not thread-safe
Keep in mind that orientation change destroys and creates your Activity again (I learned that the hard and painful way - this is how I started to follow the android-developers' blog)
...and many others.
Android Developers has good post about avoiding memory leaks due to keeping Context references. There are a lot of other interesting posts there too.
I wouldn't call them pitfalls per se, but always remember to take into account that this is not a computer that's plugged into a wall that can just be upgraded in various ways. You have an upgrade cycle of about every 2 years (the length of a standard mobile contract these days) and the hardware is (A) not the fastest and (B) static during that time.
Things to take into consideration:
1) How does the things your app does affect battery life? Are you splashing bright graphics all over the place? Running a lot of threads in the background? Services?
2) How much space does your application need to take up on the device? Is the information something that can be kept on a server and transmitted to the device for temporary use only when it's needed?
3) In regards to #2, is your app tolerant of bad/nonexistent network/mobile connections? How does it perform on the EDGE network vs 3G?
I'm sure you can come up with more but this is what I keep in mind while I'm writing my apps.