As a software developer, you can understand the problem that flutter has simplified now. These days, it is no longer enough to just develop the application for windows. The apps must also run on Android Smartphones, iOS devices and web browsers. But all thanks to flutter that now we need not to readjust and recompile the source code for different platforms. Don’t we all agree to this?
As we all know the development of mobile smart devices are booming, therefore the mobile phone multi terminal development framework has been a great trend. Ever since Google released the Flutter version in 2018 it has been used in crafting extraordinary and functional apps with seamless performance. The amazing features and characteristics of flutter have made developers experiment more with its applications.
Let’s continue reading, to know more about flutter for web development, its analysis and best practices.
What is a flutter web?
Flutter web is one of the most powerful and transforming web apps. Flutter for web is a code-based implementation for flutter which is rendered using standards based web technologies like CSS, HTML and JavaScript. Using flutter for web, you can assemble existing flutter code done in dart into a client experience. It can also be embedded into the browser and utilized in any web server.
Must read: Why should start-ups consider flutter for mobile applications?
Now the developers can build flutter apps that can be installed on Androids, iOS, Windows macOS and other Web- all from a single codebase. It’s a very powerful technology that has brought mobile development concepts, pipelines to web development and development practices.
What is the architect of flutter for the web?
Before moving further, let’s be very clear that flutter’s architect for mobile apps is different from that of web applications. The variety of tools is used for rendering the browse support. Therefore, apps will look natural on the web. The first layer of the flutter for web architects consisted of built-in themes and widget.
In this, the developers have two options of rendering engines to choose from,
- Canvaskit;
- DomCanvas.
For Flutter, the engine for web uses a Flutter web engine that generates a dart code. This dart code can be converted into CSS and HTML for implementation of the widget. However, the dart2 compiler that is the Javascript code can be deployed on browsers.
Framework (Dart)
Theming- Widgets- Rendering – Animation/ Painting/ Gestures-Foundation
Browser (C++, JS)
Canvas- JS engine- DOM
What a flutter web can do?
- Build interactive web apps in the same way as mobile apps are built.
- Streamlined the developer’s productivity for the multiplatform app.
- You are just required to write your apps once, and then deploy it to the different platforms like iOS, web, Android and desktop.
Some of the key takeaways for receptive web development with flutter are mentioned below:
- Flutter treats the complete screen as a canvas over which it transcends all HTML elements and also captures the control over it.
- The in-built widget that can be seen and helps in developing the high performing native apps.
- The only browser that is supported is chrome though, support for other browsers like safari, Edge, and Firebox is certainly under the planning.
- The API that is for web applications and mobile is exactly the same. Just a few features will not be implemented in the web version.
- The flutter for the web is still under development and evolving the default interactions. Henceforth, a web page made using flutter might provide you with a mobile app like feel as compared to a web application.
Now, since you have got an idea about how flutter for web works, let’s continue reading more for web development.
Flutter for website development
So, the best thing to develop a flutter application is that you do not require any previous experience with dart or with any other web programming language.
Let’s get started!
To set up your first web application by using flutter, you need to make sure that you should have a flutter updated version (15.4 or higher). Other than this, you also need to install dart (dart 2.3) for development reasons.
Flutter: Tips and best practices
Best practices are those professional standards that are widely acceptable in a field and are very crucial in any programming language to improve code quality, robustness, readability, and maintainability. Let’s explore those practices for designing and development of the flutter app.
Follow these best practices to improve the productivity and quality of the code:
Naming convention:
- Enums, classes, typedefs and extension names should be in UpperCamelCase.
- Packages, libraries, directories and other source file names should be in snake_case(lowercase_with_underscore).
- Constants, variables, parameters, and the named parameters should be in LowerCamelCase.
Make use of the relative imports for the files in lib:
When you use the relative and absolute import together then, it is likely to create confusion since the same class gets imported from two ways differently. To avoid these cases we must use a relative path in lib/ folder.
Specify the types for class members:
You should always specify the type of member when its value type is known to you. Try avoiding the use of ‘var’ whenever possible.
Avoid usage of ‘as’; rather use ‘is’ operator:
As we all know, many times it happens that we need to render a widget based on some condition in the row or column. In case, the conditional expression returns null then in any case we should use if condition only.
Use ’?.’ And ‘??’ operators:
Prefer using ‘?.’ (in case of null aware) and ‘??’ (if null) operators rather than null checks in conditional expressions.
Use spread collection
When your existing items are already stocked in another collection, the spread collection syntax leads to simpler code.
Make use of the cascade operator:
If you need to perform a sequence of operators on the same object, then you should make use of the cascades (..) operator.
Make use of the raw string:
A raw string can be useful to you to avoid escaping backslashes and dollars.
Don’t initialize variables ‘null’ explicitly:
While using dart, the variables are automatically initialized to null, when its value is not specified. So, adding ‘null’ is redundant and unneeded.
Make use of the expression function bodies:
For functions containing only expression; you can make use of an expression function. The arrow (=>) notation has been used for the expression function.
Avoid call like ‘print ( )’:
Debugprint ( ) and print ( ) are both used for logging in the console. In case you are using print ( ) and the output is too much at once, the Androids sometimes tend to discard some of the log lines. So, to avoid this issue try using debugprint ( ).
Split the widget into different widgets:
When ‘setState ( )’ is called on a state then all the descendant widgets will be rebuilt. However, split the widget into small widgets so the setState ( ) calls to the part of subtree whose UI actually needs to be changed.
Make use of ListView.Builder for a long set of list:
When you are working on a very large list or infinite lists, it is advised and highly recommended to use a ‘listview’ builder in order to improve its performance.
The default ‘ListView’ constructor helps to build the whole list at once. However, ‘ListView.Builder’ creates a lazy list so that when the user is scrolling down the list, flutter builds a widget on demand immediately.
Make use of Const in widgets:
The widget will not tend to change when setState calls, we should define it as a constant. It will prevent the widget to rebuild and therefore, will help in improving performance.
Open a channel
Incorporating the feature to close a survey is one of the core objectives of creating a channel. But to accomplish this task, you need to create method channels.
First, focus your attention on the Flutter module. Prior to presenting a controller with it, you need to insert the subsequent lines for the iOS platform.
Here’s an illustration for its coding for your reference.
let channel = FlutterMethodChannel(name: “survey_channel”, binaryMessenger: controller)
channel.invokeMethod(“prepare”, arguments: user.fullName)
channel.setMethodCallHandler { [weak self] call, result in
switch call.method {
case “close”:
self?.dismiss(animated: true, completion: nil)
result(nil)
default:
result(FlutterMethodNotImplemented)
}
}
The aforementioned example involves a new channel with the “FlutterViewController” object. The latter is in the form of a ‘binaryMessenger”. You can replace it with any other channel name depending on the needs of your project. However, you will need to use the same channel name on all sides.
You need to open a channel. Next, you need to furnish the full name of a user to the Flutter-module. You can use the prepare method for this purpose. Thereafter, you need to establish a handler for the Flutter-module.
Now use the following coding with the Flutter module:
class _SurveyPageState extends State<SurveyPage> {
bool showCloseAction = false;
String fullname = ”;
static const apiChannel = const MethodChannel(‘survey_channel’);
@override
void initState() {
apiChannel.setMethodCallHandler(_handleMethod);
super.initState();
}
void close() {
apiChannel.invokeMethod(‘close’);
}
Future<dynamic> handleMethod(MethodCall call) async {
switch(call.method) {
case ‘prepare’:
setState(() {
fullname = (call.arguments as String) ?? ”;
showCloseAction = true;
});
return Future.value();
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
leading: showCloseAction ? IconButton(icon: Icon(Icons.close), onPressed: close,) : null,
),
body: … // this part is not changed yet
);
}
}
Related read: Flutter framework bridging mobile, desktop, web and embedded
Flutter app development good practices
Normally flutter apps are performed by default, so you just need to avoid certain pitfalls to get good performance instead of micro-optimizing with complicated profiling tools.
Here are some tricks and tips about flutter development:
- Controlling build ( ) cost: Avoid costly and repetitive work in build ( ) methods. Since, the build ( ) method is invoked easily when ancestor widgets rebuild.
- Use effects only when needed: you should use effects very carefully. It can be expensive to use. Some of them include saveLayer ( ) behind, which can result in an expensive operation.
- Build and display frame in 16ms: If your frames are rendering and performing well under 16ms total in profile mode, it is likely that you don’t have to worry about the performance. Even in case any pitfall performance applies, you should still be aiming to build and render a frame at the earliest.
- Don’t try to make much costly operations in build method: Look, what I meant by costly operations? Meaning, where the operation requires many resources, a lot of memory and async calls.
- Avoid large trees and slit your code into small widgets: you should always divide our code into small reusable widgets not only to promote its reusability but also to improve its reading. So, basically the code should be split into various widgets based on encapsulation.
- Use absolute positioning when it’s really necessary: Since, many developers’ position elements on the “hard” screen are asymmetrical vertical padding. So, that is ideally for the application that will work on your own phones only. Rather, applications that are intended for the production content. It would be better to use the values that can adapt to the size of the screen.
- Use widgets to build UI elements: it is advised to use widgets instead of functions to build UI elements, it will be great for code reusability. If you have to use parts of the tree on different screens then undoubtedly its widget time!!
- Choice of widget matters: It is very important to choose the right widget to use when we require building a view. Always keep in mind to check if a native widget achieves a shape that you wanted to reproduce. A bad choice of widget can lead to a lot of useless code
- Dealing with API’s: With API’s, I highly recommend using the future builder widget. It gives you more control, less code to write as well as is built-in (XD).
- Only use packages when necessary: Do not make use of packages to do any task that you can also do manually, until and unless you don’t have enough time.
- Dealing with lists: Make use of the default constructor that is Listview for rendering small lists. For long ones, you can use the ListView.builder constructor which renders the list elements as the users scroll them.
Conclusion
Now, this might have given you a great insight to make your flutter code more presentable, readable while improving your app’s performance.
Flutter is one of the most promising UI tool kits that provides you with developers and every essential tool that is required for the development of a classic project.