I daresay every programmer knows the refreshing feeling when a new project begins. At the early stage, software functions are created fast, decisions are made over coffee and meetings are limited to coming over to a colleague’s desk. The situation changes together with the development of the system: due to growing complexity and relationships between its elements, a single programmer is not able to know every nook and cranny of the application. Introducing a new function may affect another, remote element of the system, so it requires consulting other teams. There are more and more people involved in meetings, which gain a more formal footing. The swelling of the system results in decrease of productivity. In such situations, companies take on more staff to enlarge the team, but is is almost always a dead-end. The communication cost keeps growing and outgrows the benefits of having extra workforce.
Frederick Brooks in his essay The Mythical Man-Month describes the traps connected with assuming that in the process of creating software a human being and time are interchangeable resources. The bigger the complexity of a project, the more time is needed for communication, organizing formal meetings and making sure that all members of all teams are kept up-to-date. The more relationships there are between tasks in a project, the more slowly the amount of time needed to finish it decreases, despite enlarging the team. In some cases, it even begins to increase.
These deliberations can be simplified and phrased as Brooks’ Law:
Adding manpower to a late software project makes it later.
What is micro frontend? Goliath versus the army of Davids
Micro frontend is not a new way of programming frontend, it is an architectural approach which differs from other models mostly by team structure. Traditional monolithic architectures, and consequently teams working on them, are built horizontally, with specialists focused on competences. Micro frontend approach gathers people according to customer need or use case, which means dividing the application vertically user story or customer journey. This way, every team has got cross-section competences and creates particular layers of software from database up to frontend, independently of other teams involved in the project.
Teams provide their own frontend in the form of page or fragment, realizing one customer need or use case. There is no need to divide the source code, libraries or even frameworks: every team is free to adjust the best technology to their case, there is no need to compromise with the other part of the application. Pages and fragments are self-contained, and all project decisions are taken locally, within a team. If a team works on a page which will include another team’s fragment, there is a placeholder inserted in its place. No elements are directly retrieved from other teams’ repositories. A working fragment is immersed in the page only during the integration stage.
Frontend integration is a stage at which all delivered pages and fragments are connected to make cohesive interface. Only now it is necessary to ensure interactions between fragments which are placed on the same page and affect one another. The final editing can be done using the following tools:
- Client-side: Ajax, iframes, Web Components, single-spa, Allegro OpBox, Project Mosaic
- Server-side: ESI, SSI, Podium, Tailor
- Page transitions: html link, App Shell, single-spa
The approach described here carries technical overheads. It is necessary to make particular project arrangements at the early stage of development in order to minimize them effectively:
In the case of backend, the problem of bandwidth or limiting computational resources needed to run an application can be solved locally within the company structures. At the front, the limit is set by the network connection and the end user browser. In micro frontend approach usually more code is run in the browser than in an analogical project with monolithic frontend. Due to this, every team should pay attention to web performance.
- Graphical user interface (GUI)
Jakob Nielsen, a leading authority in designing user experience and human-computer interaction, has proven that internal coherence is one of the most important factors affecting the usefulness of an IT system. Internal coherence concerns elements such as graphical elements of interface – like buttons, tables, inputs etc, which must look and work the same within the whole application. In micro frontend architecture it means that every team should create pages and fragments using the same design system. It may be connected with limiting team autonomy by imposing UI library or additional load of integration layer.
- Information siloses
Team autonomy does not mean its total isolation. Using frontend architecture one should remember that autonomy of teams does not rule out using the same solutions wherever it improves productivity. There is nothing to prevent every team from using the same framework (being free to accept or freeze the version within one team) or choosing the same infrastructure to detect errors.
Why is it worth using micro frontends?
In the light of the above assumptions, it may seem that classical approach to frontend, in which one team works on the whole application with one technological stack, and divisions within the team are limited only to being responsible for particular components and screens, has more benefits than using micro frontends. That is why it is good to be aware of a number of advantages of resigning from monolithic frontend:
- Faster development of features and iterations in sprints
Communication in a team is costly and – according to Brooks’ postulates – together with the complexity of a project, rises its cost. When we create a monolith and, at an advanced stage of the project, we want to use a new library, we must consult it with the whole team, together analyze potential influence of the changes on other parts of the application and discuss the way of implementation. The bigger the system and the team, the more costly it is. When we make micro frontends and want to use a new library, we simply use a new library. Development of new elements of the system does not require consultation with other teams. All necessary competences are already here. It is not necessary to wait for the input from other teams, it is not necessary to discuss priorities.
- Easier system upgrade and scaling
Implementing a new technology, updating libraries or advanced extensions does not require a discussion and planning troublesome migration. What is more, all changes are implemented only where it is really needed. A well run integration is a smaller load than maintenance of technologically coherent frontend.
- Focus on customer needs
Due to the division of duties along customer journey, and not the system architecture, it is possible to adjust solutions to actual customer needs better and avoid a number of compromises connected with connections between the elements of the system.
- A smaller load for a developer
The system realized in a vertical structure makes it easier for a single programmer to concentrate on the task, without focusing on the whole application. There is less code stored in the repository, it is easier to understand the code, test it and refactorate, and also to distribute it independently. The error risk is limited to a much smaller area and the behaviour of elements is much more predictable because they don’t share the state with other parts of the application.
Why is it not worth using micro frontends?
Despite a number of advantages, micro frontend has its disadvantages too, which may result in giving up this approach while choosing architecture. Reducing the inconveniences of monolith does not mean that there are no problems left, it means that a completely new type of problems appears.
- UI integration
Although technologies that integrate frontend exist and develop, not all tools cooperate with one another well. For instance, according to Custom Elements Everywhere report, a popular framework React passes only 71% of support tests for Web Components. This means, selecting the right technological stack may present a big challenge, and full autonomy of a team, assumed before, may become purely theoretical.
- Technical costs
The aforementioned potential efficiency problems, resulting from running a relatively larger amount of code in the browser, require paying special attention to web performance. This means applying certain communication load to teams. Besides this, reducing the complexity of running particular ‘plasters’ of the application does not mean that the complexity disappears entirely. The part of it which is avoided in frontend, is pushed into the integration layer. This does not mean that the problem of distribution is bigger than in monolith, it means it is a problem of different nature.
- Precise cuts
The division of application according to user needs in a way allowing for real autonomy of every team and coming closer to the ideal of shared nothing concept requires profound understanding of the system in terms of business and user experience. Incompetent division of application into vertical systems may make it necessary to reorganize teams or make some teams dependent on others. This leads to returning to all problems of monolithic architecture.
Summing up: endless burden of compromise
Micro frontend approach has been successfully implemented by IKEA, Zalando, Allegro, Amazon or Spotify. For a reason, most of the enterprises mentioned are e-commerce, there are frequent changes occurring, and the system is divided into front-office and back-office. Focusing teams on use cases, not on technical layers of the system, allows to avoid unnecessary doubling of discussion about the way particular components work and to introduce novelty as quickly as possible.
Sometimes, however, introducing micro frontends may turn out to be a dead end. If a project is small, we have a handful of programmers at our disposal and there are no communication problems within the team, then transposing the whole architecture generates unnecessary organizational complexity. In big projects though, if the scope of a single use case exceeds the browser and must be realizes on different devices, one team may not deal with it. For instance Netflix, whose services are accessible on almost every platform, from mobile phones to game consoles. In this situation it is advisable to create a separate team for every platform, even if different teams will be realizing the same user need.
To sum up, properly implemented concept of micro frontends may have a very positive influence on productivity and motivation of the team and may accelerate system development. At the same time, one shouldn’t use this approach unreflectively, if it is not necessary. It makes no sense to criticize monolith only because it brings about problems in huge applications. We should remember that architecture is for the system, not the other way round.