The idea of micro frontends is all the rage right now. It's been gaining traction over the years, and we’ve noticed more clients asking us about it. Although it’s an incredible solution for a lot of use cases, it can be cumbersome if your organization’s expectations are not properly set. Here are five considerations to help you determine if the micro frontend idea is right for your needs.

Before jumping in, let’s have a quick review of what micro frontends are. There are many different approaches and definitions. However, the one we’ll consider in this article is from micro-frontends.org.

What Are Micro Frontends?

Micro frontends are distinct vertical slices of a web application that encompass the frontend, backend service, and database. This enables you to break down a monolithic web application into microservices.

On the frontend you can use Angular Elements, Stencil, Polymer or Nutmeg to create a Custom Element, which is a custom HTML element that loads your component.

On the backend, the component will communicate with its very own HTTP API service and a database specifically set up for it.

You can use this concept to tie different technology stacks together as well. For example, one component could use Angular, while another uses React at the same route on the frontend. Sounds straightforward and useful, right? However, there are a few nuances that you should know when considering whether to choose micro frontends.

1. Consider the size of your team

Micro frontends enable teams to develop and deploy features end-to-end from UI to DB on large web applications, faster. An independent team can own and maintain a component slice without worrying about sharing technology or a release process with other teams. That means when a team uses components from other teams, all they need to know is the custom HTML element and its attributes.

<mi-account 
    data={[[40], [50], [50]]} 
    headings={["Account", "Balance"]}> 
</mi-account>

Furthermore, companies with multiple teams each using a different frontend framework can create a unified component library. For shared code like CSS, the DOM, events, local storage, and cookies, teams would agree on a namespace convention to avoid stepping on each other’s toes.

Some of the benefits are lost when there is only one small team working on the web application. In fact, the overhead created by micro frontends makes it harder for a team to manage components. A developer would have to switch to a different coding and deployment practice for each component slice they work on, which results in context switching and slower development. Although the team could establish common practices across components, there is a risk of components deviating. There may still be benefits to using micro frontends with a small team of developers.

“The thing is, the Frontend Platform team can’t just disappear for 6+ months and come back with a shiny new environment. It is too risky.” - Ben Ilegbodu

Breaking up a monolithic application into micro frontends may help to change technologies for an existing application. The team could deliver value incrementally by launching portions of the application without racking up much technology debt anytime there is a change in the existing application.

2. How components communicate with frameworks

Micro frontends require all frontend code relating to a component to be contained within the Custom Element. Therefore, it relies on the DOM (element attributes and events) to pass information across components, as opposed to a shared library like a publish/subscribe system. The DOM is the API.

When a parent component wants to communicate to its child component, it makes sense to use element attributes to pass data. This is also known as the declarative approach and React always uses it when passing data to a Custom Element. However, this could create problems for complex data like objects or arrays, especially because you need to stringify them. It is expensive, and any object references will be lost.

<mi-account 
    data={[[object Object], [object Object]]}> 
</mi-account>

When a child component wants to communicate to a parent or sibling component, it makes sense to dispatch custom browser events. However, DOM events require more work when using React.

React uses its own event system and cannot directly listen for native DOM events coming from a Custom Element.

One fix for both problems mentioned above is to reference the element using the ref attribute and attaching event listeners to it.

<mi-account 
    ref={el => el.bar = baz}> 
</mi-account>

The approach seems unnecessary because it prevents the use of Javascript properties for all attributes. There are a few proposals on how to support Javascript properties by default for React 17, but nothing is yet announced.

3. There’s more than one way to divide your web components

Since micro frontends isolate the code of each component, they allow teams to convert, update or scale components incrementally without a significant upfront investment. Technically everything could be a component, even the parent element. In the below illustration of the Mi Bank sample app, the thin parent component calls several child components to build out the page. The child components can be further broken down into highly reusable shared components that can be part of a core component library and shared across the team.

Thin parent component
Child component (account) Child component (investment) ...
Shared components

In this model, there would be a team assigned to the parent component: one team assigned to each child component, and maybe another team assigned to shared components.

An alternative solution is not to take the purists approach to micro frontends; not everything has to be a web component. For example, we can eliminate the thin parent component and have a team responsible for the whole web app, except for a few child components. Each child component is a distinct vertical slice of the web application that encompasses the frontend, backend service, and database. This enables a team to break down a monolithic web application into microservices without being too granular.

Web app
  Child component
Shared components

4. Just because you could use multiple client-side libraries and frameworks doesn’t mean you should

Should a team use React, Angular, or Vue for the frontend of a particular component? There are pros and cons for each, and there are reasons why one library or framework fits better in a situation over the others. I’m not going to get into that debate here. Regardless of your choice, keep in mind you are choosing the frameworks so that you can build your web application; you are not building the web application just so you can use the frameworks. As Evan You said during his presentation at Rangle.io’s Vue meetup, the complexity of the libraries and frameworks you use should not overshadow the complexity of the overall web application.

Just like with any architecture, the users will benefit from reducing the number of libraries and frameworks you are loading on the client-side.

Adding another framework, the user experience will become slower due to the additional load. Whenever possible, the teams should mutually agree on using the same JavaScript framework. On the other hand, the time-to-market benefits of an offshore Angular team might be lost if they try converting to React to align with the highly skilled in-house team for example. A slower time-to-market may result in a worse user experience compared to the additional load from a second framework.

Let's assume the teams can agree on the same JavaScript framework. Great! Now the teams need to decide if they’re gaining efficiencies on development and deployment from the independence that comes with using micro frontends.

5. You can use ESI and a skeleton UI to improve SEO and perceived performance

For perceived performance optimization, implementing Server Side Rendering (SSR) with Progressive Enhancement for your frontend application is generally recommended, especially when improving SEO is a goal. You can continue the spirit of SSR with micro frontends by incorporating your Custom Element using Edge Side Includes (ESI). ESI can even support personalization.

For some organizations, there might be barriers to implementing a full ESI solution, and SEO might not be a concern for their applications. In these cases, Client Side Rendering (CSR) is the better choice. The micro frontend Custom Element can be loaded using AJAX. This approach can cause layout jumping issues, especially if the loading content changes the initial structure of the page. A skeleton UI can help keep the structure of the layout before content is loaded.

Conclusion

The micro frontends approach is a great technique to help divide the workload for multiple teams and to isolate code for each Custom Element. Due to the extra overhead, the considerations in this article will hopefully help before deciding to use this technique. It might not be a good idea to opt for the added complexity before you actually need it!

Interested in learning more about micro frontends? Follow this link to a recording of our webinar, 'The Key to Scaling Single Page Applications'.

Resources & Further Reading