Micro-frontends has been a hyped topic for the last several years but unfortunately, it is hard to find ready to production solution. We built in-house open-source solution that allows us to deliver more than 100 apps continuously. Micro-frontends is not only about code splitting it is about the full development cycle and I will try to explain to you how we use it in production.
Browser. FrontEnd Frameworks. Gateway. Server. Scaling. Delivery.
7. · Increase Resilience
· Improved scalability
· The ability to use the right tool for the right task
· Fast and flexible delivery
· Easier debugging and maintenance
· Improved ROI with reduced TCO
· Mitigate Convey Law Risk
Reasons to use Microservices
11. 2015 – We have started migrating our monolith to microservices.
2016 – Monolith becomes smaller. Microservices grow. Frontend
remains unchanged.
2017 – Monolith becomes smaller and smaller. Microservices are
everywhere. Frontend remains unchanged.
2018 – What to do with frontend?
History
12. How usually Frontend looks
like in huge projects
Service [1]
Service [2]
Service [3]
Frontend
Gateway
14. What we really had?
· CMS served tones Frontend pages
· Some separate FE services on NodeJS
· No rules
· No agreement
· 16 Lighthouse Desktop Score
· Dozens of unknown scripts loading
· Multiple version of same dependencies
15. Service [1]
Service [2]
Service [3]
Frontend
Gateway Backend for
Frontend [1]
Backend for
Frontend [2]
Our next step is frontend
extraction
16. Benefits
· Independent deploys
· Frontend agnostic approach
· Developers can use modern technology
· Development Experience
· Faster changes
17. Enough? Almost…
· What about structural consistency?
· What about UI consistency?
· What about cross dependent releases?
· What about sharing UI functionality?
· What about reusing part of UI on different pages?
19. Goals
· Page consists of several fragments
· Fragment is independent application
· Application supports client side routing
· SSR should be supported
· UI have to be consistent
20. Requirements
· HTML Page is delivered by layout streaming system
· A unit of streaming is a fragment
· Streaming is lighting fase
· Fragment is a regular frontend application
· Framework Agnostic
· CSS Isolated
· Support Global Routes
· Fragment Delivery is Independent
· Fragment knows nothing about others
· Code sharing
21. Organizational goals
· Mitigate Convey Law Risks
· Team is independent unit
· Application and system should be testable and reliable
· Avoid communication overkill
24. But in reality…
Service [1]
Service [2]
Service [3]
Gateway
Frontend
Microservice
Engine
Fragment [1]
Fragment [2]
Fragment [3]
Scary Part of
Frontend
25. Full Architecture View
Service [1]
Service [2]
Service [3]
Gateway
Frontend
Microservice
Engine
Fragment [1]
Fragment [2]
Fragment [3]
Frontend
Microservice
Registry
App #1
App #2
App #3
26. What is Microservice Engine?
Web Service responsible for processing
incoming requests, discover page
fragments, communicate to fragment
services and form HTML.
27. What is Microservice Registry?
Web Service with persistent storage that
manage basic entities like routes,
template, fragments and their relationship.
30. How it works together. Server Side
Browser Gateway
Frontend
Microservice
Engine
Frontend
Microservice
Registry
Fragments
Form HTTP
Response
HTML Inject Scripts
Inject JSON
configuration
Object
31. How it works together. Client Side
Browser
Load
Microservice
Engine Script
Load Injected
Fragment
Scripts
Parse
Configuration
Object
Match Route
Load ESM
Modules for
Fragments
Render/Hydrate
Applications
42. Mount
mount = async (props: LifecycleFnProps): Promise<Root> => {
const slotNode = props.domElementGetter();
const root = createRoot(slotNode);
root.render(<div>Hello World</div>);
return Promise.resolve(root);
};
This lifecycle function will be called whenever the registered
application is not mounted, but it is ready to be. This function
should create DOM elements, DOM event listeners, etc. to
render content to the user.
43. Unmount
This lifecycle function will be called whenever the registered
application is mounted. When called, this function should
clean up all DOM elements, DOM event listeners, leaked
memory, globals, observable subscriptions, etc.
unmount = async () => {
const reactRoot = this.getRoot();
if (reactRoot) {
reactRoot.unmount();
}
};
45. Server Side Integration
With every request for SSR content from the app ILC sends the
following meta-information as query params:
• Router Properties
• BasePath
• RequestURL
• Application Properties
• Header x-request-uri. Request URL string. This contains only
the URL that is present in the actual HTTP request.
46. Server Side Integration
SSR response has to contain:
• Body with HTML
• Header Link
• Header x-head-title
• Header x-head-meta
52. Developers still can…
• Choose JS Framework
• Choose CSS Framework
• Decide if SSR is Required
• Control their build process
• Control their deploy
53. SO what do we have…
Application #1
Application #2
Application #3
• MS engine allows to build pages by
fragments.
• Fragment is independent App.
• Fragment can be deploy and change part
of the page.
• Your app can support client side
navigation.
• SSR is supported.
58. Do you remember this slide?
Allow to build isomorphic routing.
Browser
Frontend
Microservice
Engine
Router
App Router [1]
App Router [2]
App Router [3]
*It is not 100% truth. I will explain later.
59. To be more precise this string…
Allow to build isomorphic routing.
Browser
Frontend
Microservice
Engine
Router
App Router [1]
App Router [2]
App Router [3]
*It is not 100% truth. I will explain later.
65. What are the reasons for this?
• Client Side Runtime Error
• Server Side Error
• Client resources are not available
• Server is not available
66. • Customer should not suffer.
• One Application with Error has not to break page.
• Business and Development can define own fault tolerance strategy.
How to react on Errors and Outage?
68. • SSR: all 5xx response codes trigger the 500 error page
configured in ILC.
• CSR: any error caught by ILC errorHander, or errors during
loading/mounting trigger the 500 error page configured in ILC.
Primary Application Type
69. • SSR: all non-2xx response codes are treated as SSR error and
the second rendering attempt will be done on the client-side.
• CSR: any error caught by ILC errorHander, or errors during
loading/mounting trigger the 500 error page configured in ILC.
Essential Application Type
70. • SSR: all non-2xx response codes are treated as SSR error and
the second rendering attempt will be done on the client-side.
• CSR: any error caught by ILC errorHander, or errors during
loading/mounting are logged without any further action.
Regular Application Type
72. What is 500 error page in
term of microservices?
73. What is an Error Page?
• Works similar to regular route
• Associated with template
• Could be associated with apps but here developer should be
carefully because all your backend can be not accessible.
75. • Route does not exists on MS Engine level
• Route does not exists on Service level
• Entity does not exists on Service level
Error 404
76. Error 404
● Route does not exists on MS Engine level
○ System renders global 404
● Route does not exists on Service level
○ Developer can decide to show own 404 or global
● Entity does not exists on Service level
○ Developer can decide to show own 404 or global
Consider that global 404 page is a regular and can handle majority of cases you have
78. Customise Page Transition UI
● MS Engine can handle re-rendering of apps on the page
● API for customising loaders
79. Page Transition Hooks
● Stop navigation and use your custom behavior such as
authentication form as an example to navigate whenever you need
(CSR).
● Redirect to a new location (CSR, SSR).
● Continue navigation (CSR, SSR).
83. Shared Library
● Client side modules designed to share between pages
● Deliver without server side only client bundle
● Consumer receive updates right after deploy
84. Using Shared Fragments
● Ensure polyfill loading
● Load Bundle With Common deps
○ React
○ Mobx
○ L10n
○ EventBus
94. Why is it performant
● Horizontal scaling of backend service
● Built-in caches
● Minimum amount of computation
● Client side logic is backend agnostic
97. Conclusion
● MS increases complexity on your frontend
● MS microservices is not about code splitting
● MS should not effect frontend dev experience
● MS should be fault tolerant
● MS should have robust monitoring system
● Local development should convenient
98. What ILC Allow
● Deliver part of the page independently
● Isomorphic Client side and Server side navigation
● Support of SSR
● Error Handling System
● Fault Tolerance System
● Solution for Local Development
● Monitoring using plugin system
● Auth Capabilities
● Multi domain support
● Configuration as a Code
● Does not break your regular experience