Flutter Web vs Angular: An analysis of what to use in 2022
Our goal is to provide up-to-date information by comparing these systems to developers who are wondering where to head in 2022 in the seemingly endless maze of web applications.
Introduction
Today’s accelerated world demands immediate access to humanity’s accumulated knowledge base. However, most of us don’t have time to visit libraries, have long phone conversations, or negotiate with consultants to answer a question that arises in the rush of everyday life. Life is getting more and more complicated, we are thirsty for knowledge, we want to understand everything, we want to dig deep into everything, and we want to look up everything. However, this would take thousands of years without the Internet.
The birth of the Internet can be traced back to the mid-1980s. The network, which was used for military and government purposes, has opened up to the public after the creation of the communication protocol family used to date: TCP / IP. Since then, not only people, but also computers can understand each other’s languages, initiate conversations, exchange files and ideas about the world, all through a network that spans the globe. The first search engine was created in the early 1990s, and soon after, the first browser was programmed. With the introduction of HTML, we dressed the raw data in clothes, and as in fashion, we began to develop stylistic trends in binary numbers. The era of web design has arrived. In 1994, Tim Berners Lee founded the World Wide Web Consortium (W3C), an international organization that laid the rules for browsing the modern age. The Holy Trinity was formed: the HTML language provided the structure of web pages, CSS provided their display parameters, and JavaScript became responsible for the logic working in the background. The Internet Explorer browser has been shipped by Microsoft as part of its operating system since the mid-decade. Only creativity could limit the possibilities. From there, the number of parties joining the technology grew exponentially, Google created its search engine, YouTube launched its video sharing service, Mark Zuckerberg and his team launched their first social network.
As the performance of computers has increased, it became possible to not only rely on the resources of servers, but also to take advantage of the capabilities of client-side devices. With the help of this, regular computers also entered the competition, we became able to produce even more complex pages without overloading the server side. New frameworks were built around the JavaScript language for faster, more optimised, and more efficient development, which eventually resulted in React, Vue.js, and then Angular. Facebook can be found behind React, Google behind Angular, and an independent development team behind Vue. Tech giants worked behind the former two, while the latter relied more on the power of community. Google, however, initiated another project besides the well-known Angular. It launched Flutter in 2017, giving us the opportunity to develop an application for both mobile and web at the same time. A whole new idea to put on top of everything we’ve thought about web development over the last decade.
We have chosen Angular and Flutter as the basis for comparison throughout this article, as the relevance of these technologies has been gathered to the deepest professional knowledge in our projects. Our goal is to provide up-to-date information by comparing these systems to developers who are wondering where to head in 2022 in the seemingly endless maze of web applications.
Flutter vs. Angular
In order to understand the differences between these two frameworks, first we must understand how they operate. Flutter is Google’s open-source framework to build native iOS and Android, Desktop (Windows, Linux, macOS) and Web apps from a single codebase. One of Flutter’s main features is that everything you see on the screen is a widget, which is the basic building block of a Flutter application. The properties of a widget describe how it should appear on the screen based on its configuration and state.
There are many advantages and also a few disadvantages of the Flutter framework. First, let’s see the benefits. Similarly to other currently used frameworks, with the help of Flutter, developers can save a tremendous amount of time when they are coding. Flutter has a ‘hot reload’ function which allows programmers to see the applied changes immediately, which fastens the process, while making it almost indistinguishable from native applications. Secondly, it has a quicker go-to-market speed than its alternatives, due to the fact that users don’t have to write platform-specific codes. The third advantage comes from Flutter’s great community, which is constantly growing and strengthening, not to mention the Google support. And finally, it is also worth mentioning that Flutter can help to attract investors by enabling developers to create MVPs (Minimum Viable Product) that are compatible across all platforms and will provide you a high-quality experience.
However, we must examine some of Flutter’s disadvantages as well. It is considered as a relatively new technology (version 1.0 was released in 2018) and therefore it might change over time. Another disadvantage is that the latest native Android and iOS innovations, new features (for example Apple Watch support) will be introduced later, due to the fact that the updates roll out first on the native SDKs. And finally, there is less Search Engine Optimisation (SEO) possibilities in Web support and that there is currently no SSR (Server Side Rendering).
Now let’s see the other popular framework, Angular. Angular is a JavaScript framework that is written in TypeScript. However, it is also an open-source front-end framework that is mainly used to develop single-page web applications (SPAs). It provides developers with a standard structure that enables them to create large applications in an easily maintainable manner, while changing the static HTML to dynamic HTML.
Let’s take a closer look at the pros and cons of using Angular. First, examine the pros. Similarly to Flutter, Angular also has numerous advantages. Such benefits include consistency, modular development structure, maintainability and TypeScript. Regarding consistency, the Angular team has developed a CLI tool, which can be helpful in creating certain repeatable blocks of code from the command line. Thanks to the modular development structure, programmers can greatly reduce development time and costs as Angular allows for easy organisation of the application’s functionality and the creation of reusable blocks of code. As for code maintainability, the framework supports it in several ways, for instance users can update with the use of a single command. And finally, since Angular is built with TypeScript, it can help developers keep their code clean and understandable, while debugging becomes easy.
We should also mention the cons of using the Angular framework. One of the biggest disadvantages is that Angular is a really complex and heavyweight framework with too many abstractions and features. In consequence, it has a steep learning curve, meaning it is quite difficult to learn the basics due to its complex modules, integrations and coding languages. In addition it also has limited SEO (Search Engine Optimisation) options.
Libraries / Deps
Angular:
As Angular is backed by Google and a large development team, expect the basic package - unlike React and Vue.js - to come with more components than the other two, so we can solve more tasks with them without downloading any 3rd party libraries. In order to start the development of the project effectively, it is essential that Node.JS, NPM package manager and Angular CLI are installed on the computer in advance.
- Angular CLI: Angular's command line interface, which is a great help in initiating projects and creating their components. Using this tool to create a “hello-world” level application based on Angular conventions and directory structure takes about 2 minutes.
- With the built-in web server, we can run and test our application locally without the need for the host to have another pre-installed web server.
- Navigation: With the built-in navigator, you can easily switch between the programme's web addresses, dynamically load the resources needed to display and operate that URL.
- Forms: Angular forms allow you to place static or even dynamic reactive forms on the screen. You can control the behaviour and validation of forms from the HTML template, or even from the code.
- HTTP Client: A simple and fast solution for connecting to REST services is the HTTP Client class, which gives the user complete control over the design of HTTP requests and the processing of responses.
Naturally, with the help of the NPM package manager we can get more advanced packages in minutes, which in most cases can be used automatically for the project. The best-known ones are the following:
- Material Design for Angular: Components of popular Material Design adapted to the operation of Angular.
- NG-Bootstrap: Similar to the previous one, Bootstrap functionality made specifically for Angular projects.
- AGM: Allows integration of Google Maps.
- Angular2-jwt: A library used for JWT authentication, with built-in HTTP interceptors that attach the user's network token to each request.
- ngrx: Allows us to integrate the managed operation of today's popular Store-based REDUX Javascript library state into our Angular application.
- NG-Select: A library that extends the basic functionality of the basic drop-down menu selection input field.
Flutter:
With the help of a good library, developers can save a tremendous amount of time while working more efficiently. Luckily, the community in Flutter is really engaged and the maintainer commitment and its continuity are definitely upwards. Fortunately, Google also often announces different community events and programmes. One of the most important programmes is the Flutter Favorite1 which contains the most important, usable and recommended approaches, packages by the Flutter team and the community as well.
Now let’s see some of the most important Flutter packages, which are the following:
- Material Design for Flutter: Components of popular Material Design are added as a default to the core Flutter library.
- Google Maps: Mostly native-specific APIs are wrapped by a package. By using the google_maps_flutter2 library, developers should not worry about maintaining iOS or Android-specific implementation.
- Dio: A mobile application must be able to communicate via the network. The dio3 library provides a powerful Http client with many useful features for instance Interceptors, Request Cancellation or timeouts etc.
- Provider: State management is still one of the hottest topics in the Flutter Community and one of the reasons is that there are so many good options. You can find your favourites, for example, Redux, which has also a Flutter variation written in Dart. Nevertheless we recommend using Provider, which is a simple but powerful approach and maintained by the Community.
- Firebase packages (FlutterFire4). If you don’t want to implement and build important backend services like Authentication, Analytics or Crash reporting for your application from scratch then you can use Google’s BaaS platform which is the Firebase. After a quick project setup you can find many supported plugins that connect your Flutter app to Firebase.
- Google fonts5.This package allows us to use any of the available fonts in our App.
The above-mentioned packages can be easily added to your project by using Pub, which is the built-in package manager for the Dart programming language and is easy to use. There exist many more Flutter libraries as well, however, in this article we only mention the most important ones. If you are interested, you can find more here6.
Responsiveness
At the dawn of web development, programmers created their websites for a certain screen size. This was a problem on the user side as issues such as unwanted scrollbar or poor space utilisation occurred on a smaller or larger screen. As time went on, more and more tools for various sizes emerged, resulting in responsive web design. The essence of responsive web design is to make the website look good on all devices. Screen elements of any size are displayed on the screen in an intelligible form. This can be done by minimising the elements, putting them in a column instead of a row, and hiding them. The three main views are usually distinguished as desktop, tablet, and mobile.
Traditional web
When we are using traditional HTML components, they are not necessarily responsive by default. If no prebuilt UI components (i.e.: Bootstrap or Material components) are used, the developer has to take care of the responsiveness of the webpage. Let's take a look at the following example:
This code is non-responsive, which means when you resize the screen, the image always stays the same size. If you want it to be responsive, you need to specify max-width 100% in the style tag:
In HTML, the picture tag can be used to assign different images to screens of a given width. Not only percentage but also pixel values can be specified. The following example basically displays the image img_car.jpg, and on a screen smaller than 600px, a smaller version of the image img_small_car.jpg is displayed.
Although text is not usually made responsive, it is possible to do so in HTML.
vw means viewport width, 1 vw = 1% of screen width. Stacked after the font size, it resizes the text according to the width of the screen. Another option to resize images, text or any kind of HTML element is using media queries. It's very easy: after the @media annotation you can specify certain conditions in parentheses. In these blocks you can refer to specific HTML elements, with the help of CSS selectors, to alter the appearance and behaviour of desired UI components. With the help of Media queries it is possible to subscribe to basic document events, for example page width or height change. If these events are fired or the conditions are met, the query automatically integrates the desired changes to the webpage. Let’s have a ‘.main’ selector in which we specify three properties: green, left alignment, 60% width.
Let’s use this selector in a div:
Using Media Query, you can specify that the ‘.main’ selector be red on a screen less than 600 pixels wide:
Of course, we can write multiple Media Query, even on the same selector, and in practice this happens very often. By using this method, a code can be easily written to devices of different sizes which changes the size and location of the elements resulting in responsive operation. As Angular is an HTML, JS, CSS framework, it relies heavily on traditional web development conventions, so we can use responsive HTML components, UI libraries, and CSS MediaQueries that were mentioned above.
Flutter
LayoutBuilder:
One way to make a widget responsive in Flutter is using the LayoutBuilder. Our widget needs to be packaged in a LayoutBuilder and we return to the widget in the builder function. The builder function gives us a new BuildContext or BoxConstraints. The former is not interesting to us at the moment in contrast to the latter since the BoxConstraints variable contains a lot of useful information. For a responsive design, the most important is the maxWidth property which specifies the current width of the screen. It is important to cover how LayoutBuilder works. When you change the screen size (width or height), LayoutBuilder rebuilds itself. This means that any widget under LayoutBuilder will be called by the build function. During the rework, we have the opportunity to create a responsive design. Let’s go for a common example where you basically have 3 different coloured Containers in a Flex, collapsing the screen below 1000 pixels, even though the Containers change direction from horizontal to vertical.
Media Query:
The task can be solved in a similar way using Media Query. The code MediaQuery.of (context) .size.width can be used to extract the width of the screen and this data can be used to determine the direction of the Flex widget. It does not only contain sizing information but screen orientation data too. The biggest difference compared to LayoutBuilder is that you don't have to wrap the Center widget, but set the width of the screen to a variable during build. It is important to note that this method also involves reloading after which the build function for the context used by MediaQuery.of (context) runs again.
These two methods determine the basis for responsive development in Flutter. In a larger application there can be several responsive widgets where we need to insert a LayoutBuilder or logical code based on the constraints.maxWidth property. To eliminate this problem we can create a custom widget in which we need to create a LayoutBuilder and its associated logic once.
Custom Responsive Widget:
In this example we created a Stateless Widget called ResponsiveLayout that returns a LayoutBuilder containing the logic. You can specify three widgets for it: desktop, tablet, and mobile widgets, out of which the last one is required since we display this in the absence of the other two.
Responsive Text:
Flutter basically does not support responsive text. This means that changing the screen size does not change the size of the text. This is the expected behaviour in most cases but there are times when we want to make the text responsive.
A good solution might be the FittedBox widget provided by the Flutter SDK. FittedBox pushes the child into constraints received from the parent widget. The FittedBox widget has a feature called fit in with which you can tell how the child should relate to their parent. It can be adjusted to width, height, it can be commanded to cover, include, or possibly fill.
Another solution is to change the font size in proportion to the width and height of the screen. There are different libraries created by the Flutter community for this but we can easily write a so-called extension function to the String type ourselves.
Test possibilities
Angular:
Angular is shipped with a testing environment that - in the presence of test files - looks at the project to issue a single command that runs the previously created tests. The framework is also suitable for measuring code coverage and we also get a visual interface that can be opened in a browser while it can be integrated into most CI / CD services. Tests can be written with the built-in, behaviour-driven Jasmin service and a JavaScript framework called Karma is responsible for running and displaying these tests.
Basics of testing:
The controllers of our Angular application are the components responsible for the logic behind the UI. Here we can query the elements of the DOM and influence their operation. During testing, we can observe business logic and user interface changes at the same time.
With the help of Jasmin, you can:
- Describe (string, function): You can create a test suite which will be a collection of logically related tests. Before running the group tests, you can perform preconfigurations (beforeEach) and then restore the system to its original state (afterEach).
- It (string, function): You can create separate tests within the test suite.
- Expect (actual): And within a given test we can check the behaviour of the element we want to test.
Although you can create the Angular components used in the test yourself it is highly recommended to use TestBed which takes control of the components and obscures the hassle of the life cycle of that component. It is a good idea to configure TestBed in the beforeEach function.
Within the tests, we access the variables and functions of the component:
We can examine the elements of the UI as follows:
const fixture = TestBed.createComponent(AppComponent);
fixture.detectChanges();
const compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('h1').textContent).toContain('Welcome to angular-component-testing!');
By detecting the change, we can also examine the input parameters of a given component.
It is also possible to receive and test the emitted events from the component:
Flutter:
The more features your application has, the more difficult it will be to test it manually. Automated testing helps to ensure that your application works properly before it goes live while keeping up with its features and bug fixes.
Automated testing can be classified by three distinct categories:
- Unit test: evaluates a single function, method or class.
- Widget test (called a unit test in other UI frameworks): tests a single widget.
- Integration test: tests an entire application or a large part of an application.
In general, a well-tested application has a lot of unit and widget tests that are tracked by code coverage as well as enough integration tests to cover all major use cases.
With visuals, it is often difficult to express accuracy. Someone can do a lot of specific checks for i.e.: the size, the position or the style of an element but the entire composition on the screen may be wrong, weird, or not aesthetic. Although people can’t easily tell when something is wrong because expected results are difficult to express, automation has traditionally not been very helpful. As a result, testing an application's visuals requires some actual people to visually review the end result which in return can slow down the entire development process and the creation of new features.
One approach to this problem is screenshot testing, which involves taking a series of screenshots of your app and then comparing them to a reference screenshot. Any deviation between screenshot pairs will be marked for further revision. This process is simplified by Flutter Gold. It is an automation tool that allows to render and capture Flutter widgets as screenshots, save them as bases in a custom repository, and compare each reference screenshot with those generated at compile time after changes.
Conclusion
There are many aspects, pros and cons, support and testing options and downloadable add-ons. So, based on what has been said, which technology should a developer choose or which one is better, if any? The answer is not evident. If one wants to try modern concepts of proven methods it is worth moving towards HTML-based SPA frameworks such as Angular, React or Vue.js. With these methods we can develop websites mostly but with their responsive options we don’t have to worry that a website opened from a mobile device will not adapt. By following the PWA (Progressive Web Application)7 policy, we can even create applications that - although opened in a browser - still appear like a phone’s native phone programme. On the other hand, it is a fact that the technology on which SPA frameworks are based is old (although proven). And we know that truly innovative things happen outside of use cases and comfort zones. We recommend Flutter for those who like to experiment, try new things and want to approach web development from a completely different aspect which is a semi-mobile, semi-web perspective. An application written in Flutter translates to web, Android and iOS at the same time. One App to rule them all, One App to find them, One App to bring them all and in the darkness bind them.
We hope that you found this blog post useful! Do not hesitate to follow us, so you won’t miss interesting stories in the future either.
The professional content of this blog post was provided by:
Marcell Réti, Senior full-stack engineer,
Csongor Vogel, Lead Android & Flutter Software Engineer,
Omar Eltigani and Kristóf Rádi, Flutter developers at ff.next.
Bence Siklós, Business Analyst and Melinda Havas, Head of Marketing and Business Development formed the material into this English article.
1 https://pub.dev/flutter/favorites
2 https://pub.dev/packages/google_maps_flutter
3 https://pub.dev/packages/dio
4 https://firebase.flutter.dev/
5 https://pub.dev/packages/google_fonts
6 https://shirsh94.medium.com/20-flutter-library-that-you-should-know-about-it-8f3d33a08817
7 https://www.ffnext.io/blog/web-development-trends-progressive-web-applications-pwa
Sources used:
Web Design Museum
Code in WP
codeinwp.com
geeksforgeeks.org
zucisystems.com
https://pub.dev/flutter/favorites
https://pub.dev/packages/google_maps_flutter
https://pub.dev/packages/dio
https://firebase.flutter.dev/
https://pub.dev/packages/google_fonts
medium.com
developer.mozilla.org
w3schools.com
flutter.dev
mindmajix.com
https://flutter.dev/docs/testing
ffnext.io