logo
    • Home
    • Categories
    • About
  • en-languageEnglish
User interfaceBy Pierre Colart

Micro Frontend

Introduction

The concept of micro frontends is a software development architecture that enables decoupling of different parts of a front-end application into autonomous and independent modules. This makes it easier to develop, maintain, and deploy complex web applications.

Since 2019, micro frontends have gained in popularity and have become an attractive option for companies looking to adopt a modern approach for their front-end development architecture. This approach allows development teams to work on specific modules without affecting the rest of the application. As a result, companies can evolve faster and adapt to market changes more easily.

Many large companies such as Spotify, Zalando, and Airbnb have adopted this architecture and have seen significant benefits in terms of flexibility, scalability, and maintainability of their applications. Micro frontends have become essential for modern companies looking to stay competitive in an ever-changing market.

But what is it?

The micro frontend architecture involves decoupling different parts of a front-end web application into autonomous and independent modules, allowing these modules to coexist and communicate on the same site. This approach is similar to microservices, which aims to fragment complexity for isolated, specific, maintainable, and continuously deployable code, each independently of the others. The goal is to divide and conquer, allowing development teams to work on specific parts of the application without affecting other parts.

Why use it?

By adopting this architecture, companies can benefit from greater flexibility, increased scalability, and better maintainability of their front-end web application. Autonomous modules can be developed, tested, deployed, and updated independently, which accelerates the development process and reduces time to market. Additionally, this approach avoids dependencies between different modules, reducing the risks of errors and bugs.

Some companies struggle to maintain the quality and security of their website due to the use of outdated technologies, insufficient testing frameworks, or regressions on existing features. This makes every application evolution painful, while commercial requirements and user expectations continue to evolve.

In the most extreme cases, it may seem that the simplest solution would be to start from scratch, but this option is not always realistic for companies. Micro frontends offer an alternative by allowing the application to evolve gradually, by adding or modifying blocks of features while maintaining traffic on the site. This enables companies to be more agile and adapt more quickly to market changes.

What are we going to use?

The iframe is often considered a first step towards micro frontends architecture, but it has significant limitations in terms of responsive design, application security, and natural referencing. Therefore, it is recommended to use frontends or JS libraries to implement micro frontends.

Web Components

These libraries share common bases, APIs, and use the DOM. There are several approaches to creating micro frontends. Web Components are one of them, which are web components natively supported by most browsers. A Web Component is composed of an HTML template encapsulated in a Shadow DOM, which is a nested and hidden document in the rest of the tree.

To integrate a Web Component into an application, simply add a custom tag in the HTML code and use the Custom Elements API to define and inject the micro frontend into this tag.

In summary, using JS libraries like Web Components can offer a more performant and flexible alternative to the iframe for implementing micro frontends. These approaches allow for better management of updates, increased security, and better scalability of the web application.

 <!-- index.html -->
<html>
 <head>
  <script src="https://mes-micro frontends.fr/web-components.js" async></script>
 </head>
 <body>
   ...
    <react-web-component></react-web-component>
    <lit-element-web-component></lit-element-web-component>
    <autre-web-component></autre-web-component>
   ...
 </body>
</html>

To find Web Components libraries:

  1. Vuejs: vue-web-component-wrapper
  2. Angular: @angular/elements
  3. React: direflow
Advantages Disadvantages
Reusable and adaptable to almost all use cases Web components are generated client-side by the associated JS script. Therefore, to make them server-side if needed for natural referencing, for example, is another matter!
They can be encapsulated in a Shadow DOM that protects against any potential style conflicts Encapsulation via Shadow DOM currently poses unresolved web accessibility issues.
Web components can be nested in other web components

Web Components are very useful for encapsulating reusable services across multiple sites. For example, they can be used for displaying personalized advertisements or for integrating membership forms for insurance on e-commerce sites.

By encapsulating specific functionalities in Web Components, developers can easily reuse them on different websites, without having to rewrite the code every time. This can be particularly useful for companies that want to offer customized functionalities to their clients on different sites, while ensuring the consistency and security of the application.

In summary, Web Components are a powerful tool for companies looking to improve the efficiency of their web development and offer customized functionalities to their clients on multiple websites.

Node.js / Express / EJS

Today, many applications use Server-Side Rendering (SSR) to combine the benefits of dynamic display of client-side rendered applications and natural referencing offered by universal applications (MPA). The latter are applications that can work on different platforms, whether web browsers or servers.

The most well-known frameworks for creating universal applications are Next.js for React and Nuxt.js for Vue. Thanks to these frameworks, it is possible to design highly performant web applications that are also optimized for search engines.

The functioning of Server-Side Rendering consists of querying each application living at a different address, assigning it to an EJS (Embedded JavaScript) variable, and then rendering it based on templates. This technique allows the content of each page to be displayed based on database data, which improves loading speed and user experience.

 /* index.js */
server.get("/", (req, res) =>
 Promise.all([
   get("https://adresse-react.fr"),
   get("https://adresse-vue.fr"),
   get("https://adresse-angular.fr"),
   get("https://adresse-ember.fr")
 ])
   .then((réponses) => {
     res.render("index", {
       react: réponses[0],
       vue: réponses[1],
       angular: réponses[2],
       ember: réponses[3],
     });
   })
   .catch((erreur) => res.send(erreur.message))
)
<!-- index.ejs -->
<html>
 <head>...</head>
 <body>
    <%- react %>
    <%- vue %>
    <%- angular %>
    <%- ember %>
 </body>
</html>
Advantages Disadvantages
Natural referencing is optimized because the first display of the site and its micro frontends in the browser does not require the execution of JavaScript, which is longer to load than HTML and CSS, and not read by the majority of web crawlers. The classic problem of MPAs is present: automatic refresh when changing pages is a barrier to smooth navigation and therefore to user experience.

By using Server-Side Rendering, companies can offer a smooth and fast user experience while ensuring optimal visibility on search engines. This approach is particularly interesting for companies that need to offer a quality user experience while maximizing their online visibility.

Server-Side Rendering is an advanced web development technique that combines the advantages of dynamic display of client-side rendered applications and natural referencing offered by universal applications. The most popular frameworks for creating universal applications are Next.js and Nuxt.js. This approach is particularly interesting for companies looking to offer a fast and smooth user experience while improving their online visibility.

Single-SPA Framework

Single-SPA is a framework dedicated to implementing micro frontends from multiple Single Page Applications (SPAs). This approach is considered a separate technique in micro frontend development. Single-SPA is also known as a "meta-framework", an emerging category of frameworks designed to centralize the management of lifecycle and communication between applications.

The principle of Single-SPA is simple: each micro frontend implements three distinct methods, namely "bootstrap", "mount", and "unmount". These methods allow respectively creating the application, attaching it to the DOM, and removing it. In addition, a "ROOT" application (root-config) is used to orchestrate the dynamic positioning and display of applications based on routes.

Advantages Disadvantages
Allows migration of an existing SPA application to micro frontends through the libraries it offers The documentation does not yet allow for easy handling
Some unresolved display bugs are still observed in some cases
Since the framework is based on SPAs, server-side rendering is not a priori available.

Single-SPA is a framework dedicated to implementing micro frontends from multiple SPAs. This approach allows for centralized management of lifecycle and inter-application communication, offering great flexibility and increased scalability. Single-SPA is an interesting solution for companies looking to design modular and maintainable web applications while promoting collaboration between different development teams.

This framework is still very recent and not yet 100% reliable, although it has a lot of potential.

How do applications communicate with each other?

When services use different technologies, communication between them can be difficult. However, there are several ways to pass information from one application to another, including using URL parameters.

Attributes and properties

When using Web Components, it is possible to transmit data using attributes or properties. In the case of attributes, data can be transmitted directly via HTML code, as in the following example:

 <product-details product-id="1234567890"></product-details>

In this example, the "product-id" attribute is defined with the value "1234567890", which allows to transmit this information to the Web component.

It is also possible to transmit data using the properties of the Web component, as in the following example:

 monWebComponent.produit = {
    id: "1234567890",
    nom: "Mon produit",
    prix: 30.5
}

In this example, data is passed directly from the JavaScript code by assigning values to the properties of the "monWebComponent" component.

Advantages Disadvantages
The attributes approach is similar to passing data from parent to child components in current SPA frameworks. The data format passed as attributes is quite limited: string
Some libraries even simplify the use of attributes by passing data, such as props in React. This data is directly visible in the code, so be careful with sensitive data

It is important to note that using properties is generally preferable to using attributes, as properties allow for more dynamic and fluid interaction between different parts of the code. Unlike attributes, properties can be easily modified in real time, which allows for faster and more effective updates to the data transmitted between different Web components.

The use of attributes and properties in Web Components can be sufficient for building coordinated micro frontends within the context of the parent application. These approaches are simple to implement and enable effective communication between different Web components.

DOM / Custom Events

The Document Object Model (DOM) is a web browser interface that allows manipulation of HTML, CSS, and JavaScript elements present on a web page. One of the main features of the DOM is the management of events that occur within the web page, whether triggered by the user (e.g. a mouse click or pressing a key) or by other elements (such as a video or audio track paused).

It is possible to create and use these events to pass data via the "window" object. For example, when an event is triggered, a "CustomEvent" object can be created and passed through the "window" object so that other parts of the code can access it.

This method can be particularly useful for passing data between different micro frontends, which may be developed with different technologies and frameworks. By using DOM events to transmit data, it is possible to achieve efficient and transparent inter-application communication while maintaining the modularity and flexibility of micro frontends.

 
/* émetteur.js */
const message = {
 type: "important",
 texte: "Ce message est important",
};
// DOM Event
window.postMessage(message, "https://url-destinataire.fr");
// Custom Event
const événement = new CustomEvent("message.important", {
 detail: message
});
window.dispatchEvent(événement);
/* récepteur.js */
window.addEventListener("message.important", traitementDuMessage);
 
function traitementDuMessage(event) {
   // la donnée est accessible dans event.data ou event.detail
}

It is preferable to use Custom Events over window.postMessage() in all use cases.

Advantages Disadvantages
Simple to use Creates direct couplings between sending and receiving applications, which we specifically seek to avoid
Allows for data reactivity between micro frontends on the same page. Managing different events can quickly become complex depending on their number.

DOM events are a central element of communication between micro frontends. They offer great flexibility by allowing the transmission of rich and complex data, and can be used at any level of the application.

However, using events can also create couplings between micro frontends, which can pose long-term maintenance problems. It is therefore important to establish clear interface contracts between different applications to minimize the risks of conflicts and facilitate future developments.

It is also worth noting that micro frontends communicating with events must be simultaneously present in the DOM. In other words, if one of the micro frontends is not present on the web page, communication between applications will be impossible, which can pose problems of consistency and interoperability.

State management solution (Redux / Vuex)

The component approach proposed by modern web frameworks such as React or Vue often involves a parent-child hierarchy for data passing. This can be complex to manage, but solutions like Redux (for React) and Vuex (for Vue) offer a global state management system to make data independent of components.

This approach can also be applied to multiple micro frontends. To do this, it is possible to attach reading methods (selectors/getters) and modification methods (actions) to the window, so that all micro frontends can access them equally. This simplifies the management of shared data between different applications and improves their interoperability.

Advantages Disadvantages
The shared data is available anywhere in the application and independent of any micro frontend. This solution (via window) is still dangerous: anyone can access this element via the browser console and therefore have access to all common data in read and write mode, which is not always desirable.
Persists independently of the lifecycle of the micro frontends.
Allows the data to be updated in a reactive manner.

The current approach of state management solutions such as Redux and Vuex is often closely linked to web frameworks such as React and Vue, which limits their portability and integration with other micro frontends using other frameworks or technologies. This dependency can also make maintenance and evolution of applications more complex and costly.

However, there are already emerging alternatives, such as framework-independent state management libraries, which allow data to be stored and shared securely and independently between different micro frontends. Some of these libraries are based on concepts such as data immutability, which ensure that shared data cannot be directly modified, but only by predefined actions.

sessionStorage / localStorage / cookies

Client-side data storage via the browser is a convenient and effective way for communication between different micro frontends.

  • sessionStorage is useful for storing temporary data that should only be accessible within a single browser tab.
  • localStorage is ideal for data that needs to be shared between multiple browser tabs but does not require permanent lifespan.
  • Cookies can be used to store important information such as session identifiers or user preferences, but their use must be managed with caution due to potential security risks.
Advantages Disadvantages
Just like state management, the main advantage of these methods is to be able to access global data in read and write mode from any point in the application. The same drawbacks as before are encountered.
Independent of page changes Stored objects are only in string format
Rigid data: a modification will not result in dynamic updates in applications, but only on refresh or page change.
The localStorage storage per application is limited by browsers.

In summary, communication between micro frontends is crucial for the functioning of the overall application. However, this can be a source of complexity and coupling between different applications, which can reduce the benefits of breaking down into micro frontends. Therefore, it is important to consider the design of the architecture to minimize connections between applications and avoid anti-patterns. The different means of communication, such as events, data storage, or state management libraries, should be chosen based on the specific needs of each application and their compatibility with the breakdown into micro frontends.

Do I really need micro frontends?

It is also important to ask questions about inter-application communication: how can micro frontends communicate effectively? What data model to use? How to avoid too strong couplings between the different parts of the application?

Finally, the consequences of implementing micro frontends should not be underestimated: there may be performance decreases due to code duplication, additional management of the global application with inter-application communication, problems of consistency of the user experience, and use of CDN to counterbalance the response time of different applications.

Despite these challenges, micro frontends are an organizational solution for large-scale projects, allowing each team to focus on its scope and master it. Libraries such as LitElement and tools such as Webpack 5 are available to facilitate the configuration of micro frontends within an application. However, it is important to ask the right questions and choose the most appropriate technical solution to meet your needs.

Conclusion

If you are starting a new project and/or do not yet need a complex architecture to evolve your application, it is better to focus on the quality of your monolith before breaking it down. Indeed, breaking down your application into micro frontends can create additional complexity and introduce performance issues. In addition, there are many ways to transform your application into micro frontends when it is necessary.

On the other hand, if you feel that the complexity of your application is starting to become difficult to manage, then micro frontends may be a solution to consider. However, it is important to know how to break down your website intelligently. One approach is to segment your application based on business logic.

Pierre Colart

Passionate developer and architect who wants to share their world and discoveries in order to make things simpler for everyone.

See profil

Latest posts

Sequences, Time Series and Prediction

© 2023 Switch case. Made with by Pierre Colart