Microfrontends: the good, the bad, and the ugly
Front-end twitter exploded last week talking about ‘microfrontends’, with strong arguments and strong opinions jumping out on both sides.
Someone let me perf. profile a site using "microfrontends".
— Sean Larkin (廖肖恩) (@TheLarkInn) June 13, 2019
Memebait related: pic.twitter.com/LMldrx14Ui
The argument reminds me a lot about the “CSS in JS” argument, with both sides talking past each other.
I’ve certainly been guilty of that in the past, but this time I’m going to try for a more nuanced approach.
I think just like with CSS in JS, there are real tradeoffs and differences depending on your project and organizational constraints. There are also good approaches and bad approaches to implementing microfrontends.
So here we go, let’s take a look at the good, the bad, and the ugly of microfrontends.
First off, what exactly are microfrontends?
A ‘microfrontend architecture’ is an approach to building front-end applications modeled off of microservices.
The idea is to split your front-end into a set of independently deployable, loosely coupled applications. These applications are then assembled together to create a single user-facing application.
The technical approaches for doing this vary, with different companies doing different things, from server-side transclusion (sounds fancy, but basic equivalent of an oldschool php include
statement that crosses application barriers) to iframes to JavaScript meta-frameworks and web components.
If you’re looking to a thorough introduction to microfrontends, their benefits, and the different approaches I recommend this micro-frontends article by Cam Jackson.
The Good: Organizational Flexibility and alignment
Very similar to microservices, the advocates of microfrontends are highlighting the organization benefits of reducing cross-team dependencies. Some of the benefits of microfrontends include:
- Separate deploys for separate services
- Ability of autonomous teams to independently iterate and innovate
- Ability to organize teams around business units or products
All of these are valid benefits, especially for large and complex projects, but even smaller applications can see benefits from things like independent deploys.
When I was working on an e-commerce application back in 2010 (pre-microservices) I lived in constant fear of somehow breaking checkout due to an unrelated change. We built out extensive testing frameworks to prevent this, but in retrospect that would have been a perfect situation for an isolated service + microfrontend.
The Bad: Operational Complexity
Getting a functioning front-end environment has already dramatically increased in complexity as we’ve gone from editing static files to complex build systems, transpilation, and large frameworks. Microfrontends exacerbates that trend further, where now doing any sort of testing across your entire application may requires multiple coordinating frontends, not to mention whatever tools are used to stitch them together.
Challenges may be familiar to veterans of microservices:
- Needing to have many different applications running in development to test a complete experience
- Tracking and debug problems across the entire system
- Dealing with versioning across the system
Essentially we’re trading off simplicity within a single frontend for complexity in the overall system.
The Ugly: Performance, incoherent experiences,
There has been a lot of dunking on microfrontends going on on twitter.
Microfrontends: how can we optimize only for developers to the n'th degree. Throwing away performance, UI/AX consistency, and predicable design out the door (dramatic).
— Sean Larkin (廖肖恩) (@TheLarkInn) June 12, 2019
If, we were still doing systems programming microfrontends makes sense. But this is the web. Diff constraints
These look like pretty bad problems:
- With each team making their own technology choices, browsers may end up downloading multiple frameworks & duplicate code
- Users don’t experience your company or product in isolation. This is one of the arguments against completely scoping styles to component - the problem may be even worse with completely separated teams.
- Some of the implementations of microfrontends (particularly looking at embedding iframes) can cause huge accessibility challenges.
While advocates will argue that these don’t have to happen, this approach does seem to make it more likely that we’ll see these issues.
Compromises: The spectrum of microfrontend experience
How each of these pros or cons are will depend on you and your situation. With a small, colocated team and relatively simple product the benefits of microfrontends are small relative to the downsides, while with a large and multifaceted product and multiple distributed teams the benefits might start to outweigh the challenges.
There is also quite a spectrum of approach that may reap many of the benefits without all of the downsides.
Here's how I see the spectrum. The Microfrontend pattern that has people concerned is total independence. I've seen the pattern work when you soften it a bit with strategic collaboration between teams. Doing so mitigates the downsides. pic.twitter.com/EZhecWv0D5
— Cory House (@housecor) June 14, 2019
By sticking to a single framework choice and utilizing a coordination framework like single-spa.js you can mitigate much of the performance penalty by sharing resources & having common code downloaded only once.
With a shared component library, you could eliminate many of the user experience inconsistency problems.
Of course, at each step you give up some amount of independence. At some point, you no longer have a microfrontend architecture at all. The exact point on the spectrum that makes sense for you will depend on your product and your organization.
Which is kind of the point - engineering is all about tradeoffs, and microframeworks give you another dimension along which you can make tradeoffs.