Flutter E-Commerce App: A Curious Study
Before we start a technical bla bla bla, Let me tell a spiel. At the beginning, as usual, everything was as normal. Common-beings were just living and lazy-beings were thinking about psycho ideas and alien-beings were inventing unusual machines.
One day some alien-beings invented a machine which reduces common-beings energy to work which was nothing but extraterrestrial work and some alien-being named it as the “computer”. Hooo that was too long.
Again coming to our story, alien-beings were inventing, psycho-beings were dreaming and common-beings were running behind large screens. Accidentally due to some human-being’s work (biological doing) of aliens and psycho-beings a new category was born. What these people were doing was investing and inventing on insane machines. I say a telephone may be an iPhone or a car maybe a Tesla and lots more. According to me, the invention and investing nature is directly proportional to their psychotic level.
Ohh I forget, there was one more category born in the middle of this, once again due to human-being work of common-beings and psycho beings. This category lives like common-beings, dreams like psycho-beings and seems like real psychos.
Now you may start thinking why should I say all these unrealed things. No reasons may be the last category problem. And some others belongs to this category are,
- My teammates — the real psycho workers, they don’t know why they are doing but they are still doing.
- My PM — He told me to do this document, my psychotic level hates this definitely his too. Sadly I didn’t find another person to do this for me.
- Our CTO — He proposed to do this, I found he is a psycho-being. (For public: please don’t say it out loud) (For CTO: If you see this please don’t take action.)
- Other team members — These guys’ interference nature is directly proportional to their psychotic level.
When it comes to mobile application development there is no doubt that the native application development is the finest solution. But in real life there are other factors to consider as well, like budget, resource, timeline etc.. Perhaps the solution should be the finest but it may not be practical.
This is where we can consider hybrid application development. There are a few programming languages which facilitates hybrid app development most popular are react native, flutter and ionic. The one we chose directly depends on the performance, the language support, device support, popularity, flexibility to code and so on.
Till today react-native holds the first place based on performance, support and popularity. Why should we consider Flutter then ?
As it uses an underlying C++ engine along with Skia graphics rendering, it is a clear winner in the area of performance.
The tech and path behind the hybrid app development is always the key success factor. The react-native uses partial native code conversion behind the scenes while the flutter uses one hundred percent native code conversion to facilitate optimal performance.
2. And the future.
The way the language works to facilitate the app development seems a more reliable solution. And of course it doesn’t seem a use and throw programming solution, the assumption is because it is owned and supported by Google.
Benefits of flutter
- High productivity — Easy to code and less time frame to achieve goals
- Flexibility when to comes to UI development
- Device Compatibility
Reality to understand
- Not stabilized yet
- Number of issues reported is so high when it compared to other hybrid platform
- Issues resolving time frame are larger when we evaluate the current progress.
- iOS platform performance is not optimal till now.
E-Commerce application development is one of the biggest domains in mobile platform. Which needs several care to output the optimal performance and user experience.
When it comes real flutter based development there are many factors we have to consider and some of them are
- How feasible is this approach?
- How to provide optimal performance on both iOS and Android platforms?
- What are the best practices?
Feasibility depends on the requirements, which means if your app doesn’t talk with device hardware a lot, then your app is on a positive edge. And if your app doesn’t showcase animations a lot still you stay on the positive edge. If we say technically, using GPU resources, hardware and low level libraries directly depends on app performance. It is because flutter still undergoing development phase (Documented at 2nd March, 2021)
Our current research concluded that the flutter is able to catch up with react-native or perform better than react-native when the animations and device hardware usage is minimal.
Let’s have a detailed discussion on best practices(common practices). Let’s start from scratch. First thing to consider is Application Architecture.
Why should I follow an architecture pattern?
Every mobile developers know the relevance of app architecture, even though lets see some key benefits
- Reusable code
- Decouple business logic and UI logic
- Test driven development
- Introduce a better package structure
- Easy maintenance.
- Hassle-free enhancement and feature add.
Is Flutter comptable for popular mobile architecture’s.
Yes, completely. We are considering and talking about MVVM architecture here because it stays on a feasible position in the list and is easy to implement.
- Cleanly separates the user interface from the application business logic. Reducing the risk of technological obsolescence.
- Separates the user interface from application logic, upgrading involves minimal effort.
- ViewModel projects the data from the Model into a format that fits the View. A way to achieve data communication is Observer Design Pattern, where changes in the model are represented in the view as well, by the ViewModel. So there is a two-way data binding between ViewModel and view UI component.
- “One To Many” relationships between ViewModel and view .View is the entry point to the application
It is the developer choice to pick the file structure for the application. The architecture gives us some guidelines to achieve certain goals which can be always improved upon later. We suggest an easy to understand architecture as follows i.e., each screen has its own folder structure and associated items. Model, Service Layer, view, ViewModel and Utility layers to maintain and get transparent visibility.
An integration depict
Best practices to consider are
- Should use a state management package as view and viewModel data binding.
- Segregate routing layer
- File structure should be transparent and easy to understand
- ViewModal must satisfy general MVVM guidelines like views should never communicate directly with each, All data should be passed through view models etc..,
- It’s even better to define view state as a data model and process or save it in the model, even if it’s transient.
- Create reusable views which can bind to one or more view models.
Data communication/data management suggestions are
- Data should always provided through viewModel
- Once data is changed at model layer view model will notify the view through notifyListeners or using another best approach.
- some choices here are data binding using provider, delegation, etc,..
Why we think provider is better
- BLoC and providers are the most popular methods. Provider will surpass the BLoC pattern as it is actively recommended by the Flutter team.
- Recommended approach by Google developers
How to pass data between screens, We have multiple choices here,
- As constructor parameters and through the named route. According to MVVM, constructor pattern is closer to the guidelines.
- The Navigator provides the ability to navigate to a named route from any part of an app using a common identifier. In some cases, you might also need to pass arguments to a named route.
- For example, you might wish to navigate to the /user route and pass information about the user to that route. You can accomplish this task using the arguments parameter of the Navigator.pushNamed() method. Extract the arguments using the ModalRoute.of() method or inside an onGenerateRoute() function provided to the MaterialApp or CupertinoApp constructor.
When it comes to common styles like Bottom bar how we can adapt MVVM, our suggestions are
- By separating the navigation routes
- Introduce view modal provide menu items
When we choose MVVM for E-Commerce as it helps in:
- Easier scalability, maintainability, reusability and testability.
- Scalability allows you to expand your project as your business grows. It means that the project can handle new features and rapid growth of the user base. Developers can change front end design without touching the business logic and even able to change or migrate backend without affecting the front end.
- Work on your app doesn’t end with its release. New libraries and operating system updates are constantly coming out, and keeping an app up to date is a necessity. As your business grows and changes, you need to add new features and change the interface according to your business design and current trends on the mobile market. Maintenance is something you don’t want to spend loads of time and money on. The easier it is to maintain your app, the less money you’ll spend.
- Testability also becomes easier if your app’s architecture is built according to the separation of concerns. A QA engineer doesn’t need to test the whole application each time to check if new functionality works.Separation of concerns makes app parts independent from each other and helps to support scalability and maintainability.
A case study of Widget Consideration
Things are a little bit different when we consider an e-commerce app UI, the majority of the screens come up with a couple of products or a list of categories or some other kind of item list. Which is not only true for E-Commerce apps but also true for most mobile apps.
Every developer or an organization should have a few questions at this point, especially when it comes to hybrid app development.
- Which one is the ideal widget for listing?
- How flexible are these listing components ?
- How efficiently we can handle memory?
- Is there a feature for listing components which facilitates just in time memory allocation?
- How to give optimal performance to users ?
- Things to consider a hassle free user experience ?
Quiet natural but disaster questions in nature.
Listing can be accomplished by using any of the following components, only matters is what and how better you expect it.
- Column + Single child scroll view
- Listview Widget
- GridView Widget
The Column + ScrollView
We suggest to use this component when we have only a few items to present and which are supposed to load upfront. The scroll pick should be a wise decision otherwise it may cost more memory.
The decision normally depends on the situation. Say as an example, we can pick this component when different widgets should be grouped with a scroll functionality. Or we say if we want widgets of different layouts to be placed one below another we go for Column and ScrollView.
For complex layouts with less items we of course use it. Which means when every other widget required styling and modification from one another.
Listview & GridView Widget
ListView and GridView widgets are similar in usage and performance except the way in which they render their child items. Listview Widget shows the unlimited number of children inside it. It aligns items in row fashion on the number of times that we mention.
The outstanding advantage of using ListView is it renders only visible items on the screen. Which means only visible items are mounted and painted.
Which one is better
Conclusion is generally Listview/Grid view is better. For complex layouts with a small number of items, the performance gain may not be worth the trouble, in which case we can use SingleChildScrollView as a combination of Column widget. Even though the list view is an ideal choice at the same time its double sided sword should use it carefully to avoid performance issues.
Every application should have a couple of screens and to coordinate these screens we require a menu system. The style and position of the menu system varies and depending on the way we design the application and how far we think like a normal user. There are a couple of popular menu systems available in the market. Some of them are the bottom menu system, hamburger menu system, topbar navigation menu system etc..
We suggest a bottom menu system and why ?
User flexibility, because the thumb reaches every corner in the menu. It is easily accessible for both left and right handed users and much better when compared to a drawer. Although it is a common gesture to use a drawer to access those screens that are less frequently used, it is highly probable that a user spends more time on the screens within the navigation bar.
How flexible is the flutter bottom menu ?
Nothing is impossible. The OOTB BottomNavigatorBar Widget provided by flutter is quite customizable. Some of the features include, 2 to 5 navigation items where each item is a widget. To give an idea each item can be configured to have icon, label, animations, active and inactive views etc. If we are not satisfied with the OOTB BottomNavigationBar we are free to implement our own widget where we can draw any shapes of our likes and place it as our bottom navigation bar.
What are the best practices to handle routing in the bottom menu ?
There are certain considerations we should keep when it comes to the menu system.
- Flow should be similar to native.
- Transition should be similar to native
- Routing should be easily manageable
- Management should be easier
Flow on flutter is based on how we design the system, developers are responsible to make it like native. Native transition effects are provided by the scaffold and Material App package up to certain limits and no need to worry about it as of now. Routing and Management again falls into our hand.
If the bottom Navigation bar is to be included in multiple screen layouts, rather than adding the bottom Navigation bar in each screen, and thereby re-rendering the same widget every time it would be much better if we were to keep the Bottom Navigation bar constant across multiple screens and only modifying the body of each screen. This can be achieved using the Navigator Widget provided by flutter.
Common things to consider for a better e commerce application development are
- Reusable Widgets and components
- Choosing right component or widget
- Choosing flexible and easy to maintain architecture
- Segregate Logics, Service layers, routing coordinators
- Focus on test driven development
- Facilitate animated but lightweight environment
- Hassle free user experience
In flutter every UI element is a Widget. A widget in turn can be composed of multiple Widgets. The creation of new Widget is so swift that we almost end up creating new Widgets as we make the UI. The IDE itself comes equipped with methods to quickly extract our parts of UI code into new widgets which can be reused in different places where they are required. The best practices on Widgets integration are listed here.
Choosing right architecture is a wise decision, there are a lot of architectural patterns out there and flutter flexible to adapt each one. Out of these design patterns MVVM seems to be a viable option to start flutter development.
Choose the right component or widget, is another decision call as well as directly depends on your past experience. In Flutter a given UI can be obtained in multiple ways. To give an example, in flutter a bunch of static text can be shown using a stateless widget(which uses less memory and is more performant) as well as using a stateful widget even though stateful widget are recommended to display dynamic content.
Common E-Commerce screen considerations are,
- Home screen
- Product listing screen
- Product Details screen
- Cart Screen
- Checkout Screens
Every E-Commerce application consists of the above screens.Here I say some suggestions regarding these screens based on performance that we can capture by right pick.
The home screen can be built by using combination of
- Top appBar with search/cart/wishList navigation icon and hamburger menu
- carousel slider for banners.
- clickable image banner for promotions.
- Horizontal slider, Row/Column widgets for featured items
- Static bottom navigation bar with different screen routing. Mostly containing the frequently used screens like home, wishlist, bag, profile etc.
PLP screen can be built by combination of
- Product list can be build using gridView.builder
- A wishlist icon on each rendered product by using a stack widget.
PDP screen can be built by combination of
- A carousel slider containing different images of a specific product.
- Stack can be used for wishlist management.
- Row and Column can b used for basic details like Price, discount, offer details using a combination of Product Name, brand name and Product description using ExpansionTile
- floating action buttons can be used for cart and checkout buttons.
- Gridview for similar products using
The checkout flow is most important and it becomes complex based on the design. It can be split to multiple levels or to a single screen. The widgets we use on these screens are combinations of widgets that we used in home, plp and column based on your design.
Common performance considerations listed here in the official document.
The best always comes with risk. Here our risk comes as performance especially in iOS platform.
- The jank issue is one of the common animation issues reported so far and still no feasible solution for it.
- Avoid clipping in an animation. If possible, pre-clip the image before animating it.
- When using an AnimatedBuilder, avoid putting a subtree in the builder function that builds widgets that don’t depend on the animation. This subtree is rebuilt for every tick of the animation. Instead, build that part of the subtree once and pass it as a child to the AnimatedBuilder.
- Performance considerations should take care for for opacity animation
Credit goes to
- Me, of course all credits go to me only. Nobody can question it unless you are me. “Sarath Raveendran”
- Nobody, This nobody is my junior, who reviewed and corrected all the mistakes on this doc, actually mistakes which are in perspective of his eyes, because I never make mistakes. He always works for me and I never and will never, mention his name anywhere. But for a change mentioning his name here because I said my team members are psychos in the beginning so If anything went wrong, I will give the half credit to him. If everything seems okay for a week after publishing this, I am planning to remove him. “Jyothish Johnson”
- Two more Nobodies, again my juniors, these people actually did R & D and reported back to with their findings. Till now I don’t agree with their findings. Even though google, flutter dev team and some other peoples are agreeing with them. Still I don’t agree because a senior is unquestionable. Anyhow the credit only goes to me and nobody is going to know them as well. “Roshan Joy”, “Muhammed Shihab”