Building Micro Frontends with Stencil Web Components
This article will define micro frontends, the different approaches to building micro frontends, the definition of web components, and how to build micro frontends with Stencil.
Imagine you and five of your friends decide to build a content startup called Small News.
You deliver content at a very slow steady pace, so you build a simple website architecture to fit your needs. The website consists of a simple database with a frontend and a basic back-end setup to push and pull data. With small sections—sports, events, and entertainment—a manageable amount of routes, and a controlled content delivery system, a monolithic architecture makes sense for your Small News website.
With consistency and the right business strategy, over time Small News grows into Big News. Your company grows to 10,000 employees and several million customers. Things start to get complicated.
With more sections, more content, and more business units participating on the website, maintaining ownership of multiple sections and business units becomes difficult. Deployment slows down. Databases have to be carefully merged to align the changes. Adding a single feature to specific portions of the application could break another part of the application.
As the creator of Big News, It’s time for you to think about moving out of the monolithic structure into a more flexible architecture—a micro frontend architecture.
This article will define micro frontends, the different approaches to building micro frontends, the definition of web components, and how to build micro frontends and web components with Stencil.
Introducing micro frontends
Micro frontends are architectural patterns that allow engineering teams to divide a front-end application into multiple independent portions.
Luca Mezzalira in his book Building Micro-Frontends defines micro frontends as a “collection of decentralized artifacts that integrate into the same website.” He also defines the way to create the micro frontend framework:
Define: What are the units that need to be decentralized?
Compose: Make the units work together.
Route: Create a consistent and reliable way to make these artifacts interconnected and interdependent.
Communicate: Make a reliable way for all of the artifacts to communicate together.
Pulling data from a micro-service
Going back to the Big News example, imagine you have a sports section of the website. You not only want to give your readers news on upcoming games, but you want to provide the weather information in the city where the game is playing so the reader would know what to wear. It’s a simple value-add for the customer but is complicated to execute in a monolithic website structure.
Imagine each vertical, from sports to events to the homepage, are built on different stacks like HTML, React, Vue, and Angular. (This is obviously an exaggeration, but it can happen!) Each stack wants the same weather widget on their parts of the site. The weather team offers up their data to each vertical, but that requires each team to pull the data and implement the front-end in their own way. This leads to inconsistencies in widget design and increased cognitive load.
Now let’s say the weather service team updates the widget for security issues. Because of the way the widget is set up, every vertical needs to update the code independently, essentially coding the same component over and over. Let’s break down the numbers for this scenario:
1 week of effort on the front-end to work on code for the weather app on their vertical +
1 week of back-end effort = 2 weeks of effort for one vertical.
Let’s say 50 teams are using the same approach. That means:
2 weeks of work x 50 teams = 100 weeks. That equates to the annual salary of two full-time engineers to basically code the same thing repeatedly across all verticals!
There has to be a better way.
Micro frontend routing
Let’s try to find another way to route this micro frontend. Potentially, the weather team can own components in any instance, like jQuery plugins for HTML or React, Vue, or Angular components. But this comes with a lot of complications as well.
We would need to integrate with multiple frameworks which requires a lot of code bases to maintain. This would inflate development times and slow down deployments. There is also a lack of independent testing in this framework because it’s difficult to isolate each component and test that they all worked. Finally, this process of micro frontend routing leads to excessive communication between product owners, all for a simple request to distribute information across all verticals.
Web components
Web components are natively-supported, standardized JavaScript units that are framework agnostic. They can simplify sharing and reusing experiences because they transport their own markup, style, and logic. They are ideal to deploy reusable patterns like design systems
and are a good way to avoid repetition.
So we can now easily bring the weather component into each vertical using web components? Not so fast.
Web components are complicated
There are so many steps to create web components. Here are just a few:
- Create a class that extends HTMLElement
- Define and mount and Shadow DOM
- Add styles to the component
- Add markup with strings or by creating and maintaining elements
- Maintain State and re-render
- Define events, methods, and attributes by hand
Web components are low level by design. They are close to the DOM and are necessary to be built at this low level in order for us to build bigger things upon them.
So how can we smooth out this process of building web components? That’s where Stencil comes in.
Stencil makes frontend web components easy
Stencil by Ionic is a compiler that generates web components. It was created to be the core for the Ionic Framework, and it provides a familiar experience for the developer.
For example, if you’re a savvy React programmer, you know about 90 percent of what you need to know with Stencil. You’ll get a native and framework agnostic web component that you can use anywhere. These components will have a clear and defined method of communication inside and out.
Another benefit of using Stencil is lazy loading. If you create a hundred components and only two of them are actually rendered at the same time, only these two components will be loaded into the page.
Finally, it provides binding for common frameworks like React, Angular, and Vue which is a great way to use the browser as an integrated layer for micro frontends.
So how can we leverage Stencil compiled components when building micro frontends?
Composing and communication with micro frontends
Going back to the original example, the weather team has now created frontend web components using Stencil. This results in a series of javascript files that they deploy to their own content delivery network (CDN). The CDN is owned and operated by the weather component team—they maintain and update it.
Because javascript files are generated, the team can use a simple script file to deploy the same experience across all other verticals using the weather component. The script is deployed to the front-end of the same verticals because they’re now bound. Each vertical will pull its own data based on that configuration and render it consistently across the site.
Considerations for this approach
Here are some practices to consider when going this route.
- Pre-fetch components from the start. Whenever you use them, try to have them ready.
- Allow your components to be styled and customized.
- Establish a strategy for version control.
- Have a very strict cache strategy.
- Limit communications to @props and @events. You can use methods like focus or blur, but methods work in a separate line and can break the application’s life cycle.
- Keep your component-based micro frontend small. Don’t try to own an entire page.
- Integrate tests everywhere! Add circuit breakers. Test integrations between your component and the backend. Test the integrations between your components and the frameworks that you use. Test that your consumers are also testing their integrations between their pages and your components.
Micro frontend recap
Micro frontends are architectural patterns that are all for independent development. You can mix and match patterns to fit different business needs that you have. You have to define what architecture is going to best serve your particular system or business. Large organizations can become chaotic when separating ownership of a very large application.
Web components can be leveraged to standardize and build micro frontends. Stencil can help you achieve this by simplifying the creation and maintenance of web components. This in turn simplifies natively injecting web component based micro frontends into multiple architectures or even multiple layered micro frontend architectures. This will allow you to use the browser in a powerful and simple way to integrate services.
One more thing: Micro frontends on mobile with Ionic Portals
While implementing micro frontends in a traditional web application is relatively straightforward, getting them to work in a mobile application is a little more tricky.
If you’re looking for ways to bring micro frontend architecture to mobile, check out Ionic Portals, Ionic’s solution for delivering hyper-focused micro experiences, such as a mobile check-out flow or live chat experience, within any new or existing native iOS or Android mobile application.