<

Everything I Learned About Micro Frontends

There is a web frontend architecture called Micro Frontends. To understand this architecture, I read books and developed a simple sample web application. I would like to record everything I learned from there as minutes.

Monolithic Web Applications

Many of the concepts of microservices are typically applied to the backend. On the other hand, the frontend remains in a monolithic state.

In web applications like EC sites, various expertise (products, orders, searches, etc.) is required, and the defense range of frontend developers becomes very wide. There is a limit to developers, and one day it will become a day chased by troubleshooting.

That's where the architecture of Micro Frontends comes in.

What are Micro Frontends

It is an extension of the concept of microservices to the frontend.

micro frontends monolith-frontback-microservices
micro frontends monolith-frontback-microservices
micro frontends verticals-headline
micro frontends verticals-headline

https://micro-frontends-japanese.org

In other words, it is to microservice not only the backend but also from the backend to the frontend.

If you want to know more, please refer to the following page. It's very easy to understand.

https://micro-frontends-japanese.org/

Also, if you read the following book, https://www.manning.com/books/micro-frontends-in-action

Amazon does not talk a lot about its internal development structure. However, there are reports that the teams who run its e-commerce site have been working like this for a long time. ...

Micro frontends are indeed quite popular in the e-commerce sector. In 2012 the Otto Group, a Germany based mail order company and one of the world’s largest e-commerce players started to split up its monolith. ...

The content is as follows:

The Swedish furniture company IKEA and Zalando, one of Europe's biggest fashion retailers, have moved to this model. ...

But micro frontends are also used in other industries. Spotify organizes itself in autonomous end-to-end teams they call Squads. ...

Excerpt From: Michael Geers. “Micro Frontends in Action MEAP V03.” iBooks.

There are many cases where e-commerce sites like IKEA and Zalando adopt Micro Frontends. Although it's not public, it seems that Amazon is also working with Micro Frontends. Not only e-commerce sites, but services like Spotify also have cases where they are applied.

The Goodness of Micro Frontends

The greatest benefit I think you can get from Micro Frontends is "Localization".

By dividing the frontend for each service (products, orders, searches, etc.)

  • Improvement of service specialization
    • ex. Can focus only on the frontend of the target service
  • Improvement of service development speed
    • ex. Only need to read the source code of the target service
    • ex. Only need to update the library for the target service
    • ex. Only need to switch the framework for the target service

It might be a bit superficial, but I feel like ↑.

※ Micro Frontends is a web-based architecture.

The Difficulty of Micro Frontends

I haven't dug into this yet, but there are things like the following.

  • Even if a specific team improves, the entire team does not improve
    • ex. Even if a team succeeds in reducing webpack build time, other teams are not affected
    • ex. Security patches for libraries adopted by all teams must be updated by each team
  • Need to think about a mechanism to share with the entire team
    • ex. Design system, performance, knowledge
  • Adopting an edge technology stack makes it difficult to move team members
    • ex. A paradigm shift occurs in the technology stack

Things to Consider When Creating Micro Frontends

Making the frontend into microservices means creating HTML/CSS/JS for each service. The service that integrates these services becomes important.

There are two major integration patterns.

TypeSolutionMeritsDemerits
Server-side integrationSSI, ESI, Tailor, Podium・Good for SEO
・Less network latency for users
・Superior initial load performance
・Not good at interaction approach
Client-side integrationAjax, Iframe, Web Components・Web standard
・Robust construction by Shadow DOM
・Depends on the supported browser
・Client-side JavaScript must be enabled

Also, these two selection criteria are as follows:

TypeSelection Criteria
Server-side integrationGood loading performance and search engine ranking are project priorities
Client-side integrationBuilding an interactive application that needs to integrate the user interfaces of various teams into one screen

This time, I chose server-side integration (Podium). However, an interactive approach was also needed, so I used Hydration.

Hydration refers to the client-side process during which Vue takes over the static HTML sent by the server and turns it into dynamic DOM that can react to client-side data changes.

https://ssr.vuejs.org/guide/hydration.html

Hydration is something that allows dynamic rendering on the client side to the static HTML rendered on the server side.

※ Although client-side integration (Web Components) was fine, it was rejected due to my convenience.

Micro Frontends Sample Web App

I made a sample web app that only searches for products named apple, banana, and orange.

Here is the overview diagram.

micro frontends sample overview
micro frontends sample overview

The sample code is placed here. https://github.com/silverbirder/micro-frontends-sample-code

Services

ServiceRoleJS Framework
team-searchService to search for productsVue.js
team-productService to display productsReact.js
team-pageService to integrate servicesNo framework used (Node.js)

Mechanism

I adopted a library called Podium.

https://github.com/podium-lib/

This is a library that makes it easy to integrate front-end services. Podium has three main features.

  • @podium/podlet
    • Build a page fragment server
    • ex. team-search, team-product
  • @podium/layout
    • Collect Podlets and build the entire page layout
    • ex. team-page
  • @podium/browser
    • Provides browser-based features
    • Communication between Podlets by MessageBus
    • ex. team-search, team-product for publish/subscribe

@podium/podlet

Podlets are required to return a value called manifest.json. The manifest.json specifies the endpoints of the service and the paths of Assets (JS and CSS).

In team-search, the response result will be

$ curl https://team-search.fly.dev/manifest.json | jq .
  {
    "name": "search",
    "version": "1.0.0",
    "content": "/",
    "fallback": "",
    "assets": {
      "js": "/search/static/fragment.js",
      "css": ""
    },
    "css": [],
    "js": [
      {
        "value": "/search/static/fragment.js",
        "async": true,
        "defer": true,
        "type": "default"
      }
    ],
    "proxy": {}
  }

@podium/layout

In Layout, it fetches according to the definition of Podlet's manifest.json.

In team-page, it uses Podlet to construct the entire page as follows:

// server.js (express)
app.get(`/`, async (req, res) => {
  const incoming = res.locals.podium;

  const [searchBox] = await Promise.all([
    podletSearch.fetch(incoming, { pathname: "/search/box", query: req.query }),
  ]);
  const [items] = await Promise.all([
    podletProduct.fetch(incoming, {
      pathname: "/product/items",
      query: { id: searchBox.headers["x-product-items"] },
    }),
  ]);

  res.podiumSend(`
        <html>
            <head>
                <title>Shop</title>
                ${searchBox.js.map((js) => js.toHTML())}
                ${items.js.map((js) => js.toHTML())}
            </head>
            <body>
                <div id="app-shell">
                    ${searchBox.content}
                    ${items.content}
                </div>
            </body>
        </html>
    `);
});

In this way, it is integrated on the server side (SSR). However, interactive actions are also necessary, so it is loading js to Hydrate from Podlet.

Also, because it passes the search results of team-search (x-product-items) to team-product, SSR can be realized including the search results of products.

@podium/browser

The server side can be coordinated with podium/podlet, podium/layout. The client side can be coordinated with this @podium/browser's MessageBus.

In this sample web app, it is used in the following use cases:

  1. The user enters a keyword in the search box
  2. team-search searches for products from the keyword
  3. team-search publishes the result of 2
  4. team-product subscribes to 3 and updates the product
// team-search.js
messageBus.publish("search", "search.word", { items: hitItems });
// team-product.js
messageBus.subscribe("search", "search.word", (event) => {
  hydrate(
    <Items {...{ items: event.payload.items }} />,
    document.querySelector("#team-product-items")
  );
});

By doing this, it was possible to partially update without screen update. Interactive operations are also possible.

State management, routing

This is not yet properly made, but I think it is good to design with the following concepts:

  • State management
    • Each service manages the state. The state is not shared.
    • The integrated service manages the common state.
  • Routing
    • Each service sets the query.
    • The integrated service manages the URL path.

Others

Each service is deployed to a PaaS called fly.io.

https://fly.io/

I am using an Edge Worker that can execute SSR with CDN. This allows you to cache the SSR results and return responses quickly.

However, in the sample web app, I am not able to fully utilize its power...

※ Reference article https://mizchi.hatenablog.com/entry/2019/02/21/235403

What I learned from the sample web app

SSR + CSR (Hydration) can be realized

Even if it is server-side integration, CSR can be realized. However, there are difficulties in performance in Hydration, so this remains a challenge. Also, care must be taken with the size of the bundled javascript for CSR.

For example, there are measures to reduce the size of javascript by sharing vendor files like "shared_vendor_webpack_dll" in the following repository.

https://github.com/naltatis/micro-frontends-in-action-code

Also, zalando tailor in the following repository is a tool that shortens the overall script load completion time by streaming script load.

https://github.com/zalando/tailor

You can choose the technology stack within the service

This is often cited as a benefit in microservices. Even on the front end, you can freely choose the technology stack.

In this case, we are using React.js and Vue.js. It is also possible to switch to Riot.js or Svelte.js.

The world of front-end is characterized by rapid changes in JS frameworks, so I think this advantage is important.

However, you must return the Podium's manifest.json. At present, only Express supports Podium, so it is limited to frameworks that use Express.

Can focus on the front-end of each service

If it's a search service, you can focus solely on the front-end specialized for search. If it's a product service, you can focus solely on the display content of the product.

However, there will inevitably be requirements to collaborate with other services. I think this is the difficulty of microservices. For example, you need to consider when each service registers events.

Finally

In applications like EC sites, there are many things to do on the front-end, such as "making it easy to find products", "displaying products that make you want to buy", and "making it easy to purchase products".

If the front-end of such a service is monolithic, there will be cases where uniformity is lost or bugs are unknowingly embedded.

I believe Micro Frontends is a good architecture to tackle this increasing complexity of the front-end. However, just as there are challenges with microservices in the backend, there should also be challenges with microservices in the front-end.

In Japan, there are few examples of Micro Frontends implementation, and I think it is still developing. I hope this article will be a reference for some service.

Thank you for reading to the end.

Reference link

https://github.com/ChristianUlbrich/awesome-microfrontends

If it was helpful, support me with a ☕!

Share

Related tags