Frontend Development 15 min read

When to Adopt Micro Frontends: System Requirements, Design Guidelines, and Performance Tips

Adopt micro frontends when large, parallel development teams need independent releases, cross‑technology migration, or high‑frequency updates, and design them with a central app shell loading shared dependencies, choosing between iframe, web component, or lifecycle‑hook bundles, managing single‑ or multi‑instance routing, shared state or event‑bus communication, and optimizing performance through lazy rendering and shared library bundling.

Baidu Geek Talk
Baidu Geek Talk
Baidu Geek Talk
When to Adopt Micro Frontends: System Requirements, Design Guidelines, and Performance Tips

Micro frontends, similar to micro‑services, have become a hot topic in recent years. As monolithic single‑page applications (SPAs) grow larger, the benefits of front‑end/back‑end separation—decoupled development and independent releases—diminish, and modular decomposition becomes necessary.

1. When does a system or front‑end team need micro frontends? The article lists several pain points that indicate a micro‑frontend approach could help:

Many modules need to be developed and released in parallel.

Large development teams (e.g., >10 developers) working on relatively independent sub‑modules.

Multiple teams collaborating on the same codebase, leading to coordination overhead.

High release frequency, typical of rapidly evolving business domains.

Cross‑technology‑stack migration, where legacy code coexists with newer frameworks.

These scenarios often result in complex dependency graphs and risky roll‑backs during releases.

2. Design points to consider when building a micro‑frontend architecture

Main module and sub‑modules

The main module (often called an APP Shell or Nutshell ) loads shared dependencies, initializes the entry point, and renders sub‑applications based on routing information. Sub‑applications can be implemented in three common ways:

As an iframe (simple but limited control).

As a Web Component (requires careful browser compatibility handling).

As an independently deployed JavaScript bundle exposing lifecycle hooks (register, mount, unmount) – the most widely used approach.

Single‑instance vs. multi‑instance

In a single‑instance model, only one sub‑module is active at a time, typically driven by routing. In a multi‑instance model, multiple sub‑modules can be active simultaneously, requiring more complex routing and layout management.

Example route configuration for a single‑instance setup:

const subAppRoutes = {
  route1: 'https://your.static.server.com/app1/index.js',
  route2: 'https://my.static.server.com/app2/index.js',
  route3: 'https://other.static.server.com/app3/index.js'
};

Example route configuration for a multi‑instance setup:

const subAppRoutes = {
  route1: [
    { subApp: 'https://your.static.server.com/app1/index.js', layout: {/* layout info */} },
    { subApp: 'https://my.static.server.com/app2/index.js' }
  ],
  route2: [
    { subApp: 'https://your.static.server.com/app2/index.js' },
    { subApp: 'https://my.static.server.com/app3/index.js' }
  ],
  route3: [
    { subApp: 'https://my.static.server.com/app3/index.js' }
  ]
};

The entry module must maintain a routing map and may need a dynamic schema to describe where each micro‑frontend should be placed, enabling low‑code assembly.

Sub‑module communication

Typical communication patterns include:

Global state sharing : a shared store where one module writes changes and others react, with namespace isolation to avoid conflicts.

Event bus : modules publish and subscribe to events. Care must be taken to handle the case where a consumer is not yet instantiated—event buffering may be required.

Both patterns are generally needed for robust micro‑frontend systems.

3. Performance optimization tips

On‑demand rendering for multi‑instance apps

When many sub‑modules exist on a page, render them lazily based on viewport visibility. This reduces initial scripting and resource load time, while pre‑rendering can be used during idle periods.

Duplicate bundling reduction

Common libraries (e.g., UI components, polyfills) should be shared rather than bundled into each sub‑module. Strategies include:

Providing shared capabilities from the entry module (e.g., global AJAX, telemetry).

Extracting common code into a shared bundle, such as polyfills, and loading them only once.

Using runtime polyfill services (e.g., polyfill.io) or Webpack 5 Module Federation (cautiously in production).

Maintaining a whitelist/blacklist for polyfills and enforcing compliance via development tooling.

These approaches help keep the overall bundle size low and improve load performance.

References

Micro Frontends – Martin Fowler: https://martinfowler.com/articles/micro-frontends.html#IncrementalUpgrades

@babel/preset‑env “usage” option: https://babeljs.io/docs/en/babel-preset-env#usebuiltins

Polyfill.io: http://polyfill.io/

Webpack Module Federation: https://webpack.js.org/concepts/module-federation/

performance optimizationmodule federationfrontend architecturecode-splittingmicro frontends
Baidu Geek Talk
Written by

Baidu Geek Talk

Follow us to discover more Baidu tech insights.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.