What is the best Micro-frontend approach in large-scale projects?
Let's Analyze the choices and results of decisions
When a project is scaling up and getting bigger, it requires to have more teams and developers working on it, each team should work on a specific part of the application or website.
In this situation, there are three common approaches
- Iframe
Splitting the app into independent parts available via the link as an HTML or browser page and rendering it with an iframe. - Run-time integration
In this approach, each part of the application is independent and being developed by independent teams as a micro-frontend and is accessible via the link as an exposed address of micro-frontend remotes. - Build-time integration
Splitting the app into reusable packages or libraries that can be imported and used in each part of the app that is needed, all libs and packages will be bundled, splitting into smaller chunks to download in build time and will be execution ready.
For more details visit this article
Let’s explain in more practical detail
1. Iframe
when thinking about iframes, they let you embed an independent HTML document with its browsing context. Thus, it will be isolated from the JavaScript and CSS of the parent.
Iframe security
When you are using an iframe, you are mostly dealing with content coming from a third party over which you have no control. Thus, you are increasing the risk of having a potential vulnerability in your application or simply having to deal with a bad user experience (like annoying video autoplay ).
SEO
It is best to assume that the content displayed via iframes may not be indexed or available to appear in Google’s search results.
Performance
Every iframe on a page will increase the memory used, as well as other computing resources like your bandwidth. So you should not use iframes excessively without monitoring what’s going on, or you might end up harming your page performance.
While they can be insecure if you’re loading untrusted content, they also offer some significant benefits. So it’s better to use iframe just when required and there are no better solutions.
For more details visit this page
2. run-time integration
In this approach, there are different micro-frontend frameworks like module federation, single SPA, etc.
What are the pitfalls of using runtime integration?
Performance
Keep in mind that all run-time integrations and frameworks have performance side effects and overhead because when a page is being rendered by the browser they add extra tasks and computations to the browser.
By increasing the number of exposed remotes the overhead and performance effect increases especially when using nested micro-frontend remotes, the overall page download time, time to interact, and render blockings will increase.
In this approach, there is a host that loads microfroned remotes, if a remote needs to load other remotes at the same time this remote plays both host and remote roles. The root host or parent is a normal build-time integration project that loads remotes.
The loading process of remotes is heavy because the remotes.js file should load as well as page loading and should download javascript files and assets(styles, images, fonts) from the internet and after that execute these js files.
Thus when the number of remotes whether nested or siblings increases the number of duplicate and redundant downloads (different versions of a package) and executions will decrease the overall performance with a horrible effect.
Style override
Because of the independent developing style, override mostly occurs and after deployments, the project styles encounter conflicts and overrides.
SEO
This approach is not SEO-friendly because all the remote loading process is client-side.
Sometimes there will be chunk load errors when loading a micro-frontend page because of different cached versions of remote and nearly deployed versions.
I’ve explained these errors and solutions in this article
What are the benefits of using runtime integration?
It increases the developer experience by making each part of the application independent in all aspects like styling, package versions, deploys, etc.
Thus I highly recommend using this approach rarely, in small cases.
In large applications with more remotes and libs the best approach is build time integration.
11-micro-frontends-frameworks-you-should-know
3. build-time integration
Build-time integration is an ordinary approach like monolithic projects, most of the execution processes are handled and managed in build time.
So what is the best approach for a small project? monolithic
In large projects instead of a monolithic approach it’s recommended to use a build-time approach mono repo or poly repo.
In the mono repo approach, there are popular frameworks including NX and Lerna.
Nx has helper tools, plugins, and executors to handle and manage large projects based on libs, packages, or monolithic.
The big plus of the Nx in libs approach is using only one package.json file and it solves the problem of different versions of a package (e.g react 16.8,17,18) should be used in different parts or libs of the project thus the libs approach is better than package base approach for performance.
Conclusion
The performance rules
- Build-time integrations are much better than run-time integrations
- Single package.json is better than many package.json files
- Server-side rendering is better than client-side rendering
As much as increasing executions and renderings on the client side the performance decreases and the user has a bad experience.
Thus by considering these points, technical decisions and figuring out the bottlenecks get clear and simpler.
By the way, if this article helped you, don’t forget to clap & subscribe! 🙂
thanks.