The “micro frontends” idea has been around for a while now, with great resources such as this Tom Söderlund article, which includes a list of current existing implementations.
In this article, I would like to take an in-depth look at the reference implementation using fragments: explain what it tries to achieve, where it falls short and possible solutions to those limitations.
What are Fragments in the first place? They can be described as isolated pieces of your HTML page, built and served by independent services (and usually teams) such as Header, Product, Search, etc.
Example of an e-commerce website using different fragments to render a product page.
There are at least four benefits from typical micro services that fragments are trying to bring to the front end:
- Ease of deployments with better isolation
- Improved scalability with smaller pieces
- Technological stack isolation with API integrations
- Localized complexity with every piece easier to reason about
All of those usually lead to more autonomous and engaged teams with an improved DevOps culture.
Main implementations for fragments include:
- Zalando’s Tailor, inspired by Facebook’s BigPipe
- Web Components using Server Side Includes (Michael Geers talk)
- Web server HTML transclusion using Edge Side Includes (Gustaf Nilsson Kotte talk)
These fragments-based solutions claim technological stack isolation but in practice all those fragments are only running a single framework (often React), which is probably a good thing as client bundle size would otherwise have to include different frameworks.
However, they achieve ease of deployments, improved scalability and are easily server-side rendered. There is a small catch though.
Like on the back-end side, a distributed architecture managed by different teams slowly leads to inconsistencies and different ways of doing things. While it might not be such a big deal for back-end side systems, creating inconsistent user interfaces and user experiences is an issue most customer-facing websites cannot ignore. The split of your UI components pipelines also means more infrastructure work to build and ship them to production.
Of course there are solutions to mitigate this. Immowelt for example went for a front-end micro service boilerplate. The boilerplate includes an advanced setup of Immowelt’s front-end stack: React, Redux, Universal rendering, etc. The advantage is to reduce the time to setup for a new service, limit fragmentation, share common practices between teams but still keep flexibility.
Another solution exposed and detailed by Allegro is to compose the HTML page from the same high-level front-end components whose unit they call “Box” and to focus on sharing and reusing components. In this context, the unit or “Box” declares its data dependency and can include other “Boxes.”
Zalando also identified those issues, the most important ones for us, as a company, being the non consistent digital experience, which penalises our brand proposition, together with the high barrier to entry for contributions from other teams because of the complete technological stack required to build a new fragment.
We are currently working on a replacement for Tailor (Zalando’s fragments based approach) which we call "Interface Framework" — an architecture stack composed of the following components:
- Fashion Store API: GraphQL API aggregation layer
- Renderers: self-contained pieces of code declaring their own data dependency and visual representation
- Recommendation System: backend service which decides which renderers to display for page composition
- Rendering Engine: backend service and client-side runtime orchestrating the view composition based on the data returned by the recommendation engine
Renderers are developed using Design Systems components in a mono-repository to ensure consistency. The previously redundant fragment’s stacks are now all centralised within the rendering engine which leads to faster on-boarding and reduced time to market for feature teams developing renderers.
This new architecture also enables dynamic view composition: at any point in the user journey, the data layer can choose how the page should look for personalisation purposes. We also want our partners to be able to build renderers themselves so that they can seamlessly integrate their content within our website.
Work on the most important solutions in e-commerce: have a look at our jobs page.