Modern web application’s realities: micro frontends, server-side rendering, and PWA

Vladyslav Bezruchko
Inside the Tech by SoftServe
13 min readSep 20, 2021

Authors: Vladyslav Bezruchko, Volodymyr Fedak

This article provides an overview of single-page applications (SPA) Web Applications evolution and a sample project that can be used for micro-frontends implementation (https://github.com/SoftServeInc/mfs-accelerator ). Mentioned above sample application can be used as a reference to validate your decisions before the development (or integration) of “Enterprise” Web Applications (a kind of application used to satisfy the needs of an organization — businesses, schools, interest-based user groups, clubs, charities, and governments. In our experience, such SPAs had a huge code base up to 300K-0.5M LOCs).

Single Page Applications: good and bad parts

Nowadays, single-page applications take a crucial path in web development. Let’s start our journey from the basic definition. What is a single-page application? It’s a web application built all over a single HTML page to replicate native app behavior in the web browser. Initially, the term single-page application was first used by Steve Yen in 2005[1]. At the beginning of 2010x, a set of powerful javascript frameworks for building a single page was introduced: AngularJS, BackboneJs, etc.

During the first years, developers were happy because of new and awesome experiences working on single-page applications based on mentioned frameworks. Users also enjoyed it because web applications behaved very similar to desktop: without page reloads and having a great performance (of course, only in case a single-page app was implemented correctly). Later it occurred that there were lots of cons in single-page web application applications. Let’s go through the list of problems that single-page applications had at the early beginning:

  1. The load of the first page took too long. It’s happening because firstly browser gets a very tiny HTML with one tag <app/> and with <script> tags with JS files. The browser receives JS from the server and starts building (rendering) HTML. During this time, the user sees only a white page, and that’s a problem because, according to statistics, the more user waits the more chance that he will leave and never come back to the site.
  2. Problems with search engines (Google, Yahoo, Bing, etc.). Search engines could not render HTML and see only tiny HTML with one tag <app/> and scripts. That’s why search engines were not able to index single-page applications.
  3. Performance problems: very often, because of the pure design of frameworks or the incorrect usage of the frameworks, single-page applications became terribly slow and took lots of system (user’s browser) memory. A good example might be Angular1 watcher’s memory issues (https://stackoverflow.com/questions/9682092/how-does-data-binding-work-in-angularjs ).
  4. Compatibility problems: it was complicated and error-prone to have few frameworks working together in one application. Furthermore, different versions of frameworks were not compatible: Angular1 and Angular2+. It led to a significant problem: imagine a large enterprise company developing an application from 2013 using Angular1. In 2016 it occurred that they cannot switch to Angular2 because it’s another framework and Angular1 is promised to be deprecated. It meant that companies had to invest a solid amount of money for migration to the new Angular2 which wasn’t predictable upfront.

Natural SPAs evolution into micro frontends

Let’s firstly start this topic with the analysis of the backend microservices architectural style. Wikipedia says: “A workshop of software architects held near Venice in May 2011 used the term “microservice” to describe what the participants saw as a common architectural style that many of them had been recently exploring.” If we look at Google trends — we will see that the search term “microservices” started in 2015 became increasingly popular.

Figure 1. Growing popularity of microservices over the time

Microservices architecture style focuses on solving the scaling problem of big monolithic applications (especially in clouds). The front-end developers started to observe similar problems. People started to create SPAs at the beginning of the 2010s, and in 2015th there were many huge monolithic SPAs where every change was extra complicated, and achieving reliable performance was also a big problem. A typical example is a big company that has been working on large-scale enterprise SPA for five years. The company built a huge monolith SPA based on an old framework, deeply coupled into the application’s core, so migration to the new frameworks is very painful and expensive. At the same time, every change affected the whole application. Considering the problems with performance in such cases, we can understand why the front-end world started to think about the applicability of microservices architecture principles to SPAs. Here is where micro frontends started. The micro frontend is an architectural style where independently delivered frontend applications are composed into a greater application.

Let’s look again at Google trends. We can see that the search term “micro frontends” has become increasingly popular starting from 2018.

Figure 2. Growing popularity of the micro frontends over the time

The modern process of building next-gen web solutions requires separate teams to work on independent applications (micro frontends). Every team has its own functional scope, builds and tests process, deployment pipeline, and independent release process.

The following picture below represents that idea (a separate release new functionality in Home micro frontend without affecting all other micro frontends):

Figure 3. Typical Ci/CD setup for micro frontends

Consequently, this approach allows to:

  • Have a separate delivery pipeline for the micro frontend (it is usually represented as a group of pages)
  • Establish more scalable organizations with decoupled, autonomous teams
  • Have smaller, more cohesive, and maintainable codebases

Martin Fowler did a great micro frontends definition [2]

Nowadays there are lots of different frameworks and libraries that can help you to organize micro-frontends. We propose to concentrate on two of the most popular frameworks:

Table 1. The comparison between two the most popular frameworks/libs for micro frontends

BIT is a different philosophy in building micro frontends because initially, it’s a tool for component management that focuses on using the BIT cloud for hosting those components and organizing CI/CD for them. At the same time, Single SPA is more like just a wrapper over micro frontends.

There is always a possibility to build custom shells (wrappers) that will host micro frontends and avoid using the above library/frameworks, which will help mitigate vendor lock problems. On the other hand, it will couple your delivery team with some self-made solutions that might be hard to support in the future.

In the scope of this article, a sample application is provided (https://github.com/SoftServeInc/mfs-accelerator) with a typical micro frontend approach (usually we see such approach utilized when several teams have been working on a particular solution). It’s not required to have such a variety of frameworks however it happens in real life when different teams work in separated subprojects. Please see the diagram below:

Figure 4. Sample architecture for micro frontends application

The key point here is that over time WEB-UI teams should have resilient and “framework-agnostic” Web-UI app. In our terms “framework-agnostic” means having the possibility to extend web app with a necessary framework. On the provided sample Single SPA has been used as a shell (wrapper) for micro frontends based on Angular/React/Vue. Each micro frontend is a stand-alone SPA that knows how to bootstrap, mount and unmount itself from the DOM using Single SPA tooling. That is the only thing that couples your micro frontend to a wrapper (Single SPA ).

Another feature of the provided sample is to have an easy ability to write reusable shared UI components using any JS library/framework. It might be achieved by wrapping them with web components (a suite of different technologies allowing you to create reusable custom elements — with their functionality encapsulated away from the rest of the code via browser API). [3]

For internationalization, the i18next is used which supports all popular frameworks.

It will look similar in all frameworks(angular, react, vue), please see this example:

<mfs-button ref={refreshButton}>  {i18nnextCommonDashboard.t(“Users.”)}</mfs-button>

Figure 5. i18next ecosystem

For this article, we prepared an example that was built using the architecture approach mentioned above. SystemJS approach was used for module sharing together with Single SPA, but at the same time, you can go with Module Federation (another modern approach). In short, the Module federation is a part of webpack core which allows a JavaScript application to dynamically load code from another application — in the process, sharing dependencies. If an application consuming a federated module does not have a dependency needed by the federated code — webpack will download the missing dependency from that federated build origin. This tool should help to build micro frontend applications in a very efficient way. You only have to remember that module federation is a new technology and it became stable in Webpack 5.0.0 ( 10’th of October 2020 ). You must test it carefully in some PoC to understand if it works well with your setup. In our case, we used the standard for the Single SPA SystemJS approach, but if you tried to use Module federation with Single SPA — please let us know in the comments to this post.

To learn more about module federation please check the following articles [4, 5]

If you plan to build a micro frontend application, it makes sense to look into Monorepo, which will allow you to separate build and deployments having one codebase. There are lots of alternatives, but in our example, we used yarn workspaces for it. Yarn workspaces were selected since it’s simpler, but you can try to use a more advanced solution like LernaJS or Nx workspaces.

In PoC we did not cover cross micro frontends communication because it’s not a general use case to have such communication, and you must be very careful with it. If your micro frontends communicate too much with each other probably you need to combine them into one micro-frontend [6]

Server-side rendering as an approach for improving performance and SEO

According to this research [7], the slower page response time results in an increase in page abandonment.

Taking into account that the slow load of the first page is a weak side of SPA — this aspect might be crucial for many different business applications. Another weak part of SPA might be the problem with search engines: originally search engines were not able to render the page via js and in fact, they saw just a tag to load SPA (see picture below).

Figure 6. Typical response from the server the with first(root) SPA page.

In 2009 Google team made a proposal for making AJAX crawlable [8]. And in the middle of 201x Google crawler started to render SPA and index it. But there were some problems with it because the crawler had an old Chrome version (for example in 2019 it had 41 Chrome Version but the actual was 73). Finally in 2019 Google SEO team fixed it and now Chrome can index pages better. But still, there is a difference: sites with the classic server-side approach are now indexed faster than general SPA because for SPA Google crawler uses an additional queue (for the pages which have js and need to be rendered before indexing). You can get more details from this speech Technical SEO for JavaScript developers [eng] / Martin Splitt

So, the businesses that needed at the same time both SPA, SEO, and quick first-page load were struggling, and server-side rendering was introduced to overcome that (you can check how it’s done in the Angular ecosystem [9] ). The idea is that the NodeJS backend can build HTML using Angular, React, etc and return to the client(browser) ready page so that the user sees complete HTML in a shorter period and the search engine can index it. Originally such solutions were implemented by enthusiastic people in separate repositories, some of them became part of the framework later (for example Angular Universal). React ecosystem has Nextjs for it, vuejs has Nuxtjs, and so on. Interesting thing is that you can run NodeJS and organize server-side rendering using non-js environments like java and c# [10]

CI/CD

In the context of micro frontends, it is essential to have the right automation framework for every component. At least the following properties must be configured: code builds, integrations, static/dynamic code analysis, quality gates, and performance analysis.

Among the other parts of CI, it will be good to highlight performance analysis automation. It can be organized by integrating into CI the tool (for example Lighthouse CI by Google) which will monitor different aspects of the pages. It’s possible because the tool can connect to the browser and get different information like performance, accessibility, etc.

There is one more thing that is about the agility of a web interface to respond to business demands. What if some of the new or updated pages have to be available only to a part of the customers. And later, these changes should be rolled out to the wider audience in case the feedback is positive.

Limited availability deployments with feature toggles approach will provide the possibility to gradually release new features for specific users.

Figure 7. Feature toggle approach for new feature deployment in micro-fronted.

Mobile-first and progressive web applications

Last year, the conversion rate (the percentage of visitors to your website that complete a desired goal (a conversion) out of the total number of visitors) of mobile applications compared to desktop was growing. It means that more and more users prefer to access web applications via smartphone. That’s why we suggest paying attention to such patterns as mobile-first and PWA.

Mobile-first tells us that we have to build a web application that will be efficient on the mobile, first of all. This approach gives the following benefits:

  1. Performance (mobile devices are not so fast as desktops which force developers to optimize performance)
  2. Better Search Engine optimization (because search engines rank higher web applications which are optimized for mobile devices)
  3. Better UX (because it’s becoming easier for users to access the content)

You can read more about mobile-first here [11]

Another important approach that will allow getting more users is Progressive Web Application(PWA). According to this article, [12] PWA Progressive Web Apps are web apps that use emerging web browser APIs and features along with traditional progressive enhancement strategy to bring a native app-like user experience to cross-platform web applications. This means that you can, for example, open your PWA website in a browser on your phone and add it as an application to your home screen which will give you the possibility to use your web application as native. The main items here are:

  1. HTTPS for the contents securing
  2. Service workers (for offline support)
  3. Manifest (for the controlling on app’s appearance for the user)
  4. App Shell approach ( will give you faster page load )

Figure 8. PWA explained

In provided sample application PWA support is added to the root micro frontend wrapper (Single SPA) — you can check it here. Also, in this example, use cases related to offline support were handled via service workers.

Testing Aspect

Talking about the modern approach for building SPA we cannot forget about testing. Historically front end has not been tested well but we are sure that it is the wrong way. The testing strategy plays a crucial role in the success of the solution. We suggest using a classic approach called test pyramid when the test suite consists of three layers: unit testing, integration testing, and end-to-end (e2e) testing. The core motivations are linked to Agile objectives: reducing cycle-time, meeting frequent deadlines, rapid feedback, improved and co-located collaboration. Also, the largest part of the testing will be automated that allows having quick feedback on any change in the codebase.

Figure 9. Testing approach for SPAs

Summary

Single page Web applications had come a long way since 2005 when they were introduced. Nowadays, there are tons of JS-based frameworks that you can use to develop your SPA. If you build a simple application, you can choose the framework based on various aspects ( e.g. your developers are familiar with React or Angular ). However, suppose you are planning to build a huge application from scratch. In that case, you must be incredibly careful with your decisions not to face a case when your engineering team will be required to rewrite the majority of applications as it was with Angular1->Angular2+ migration in huge projects. The micro frontend architecture style is a helpful tool for huge applications, and it has to be as framework agnostic as possible. Additionally, use such techniques as mobile-first and PWA to improve your web application from the mobile device’s point of view.

Use provided example (https://github.com/SoftServeInc/mfs-accelerator) as a reference for your own decisions and make contributions if you find it useful.

Resources:

  1. What Compelled Single Page Applications to Jump into Trends https://www.linkedin.com/pulse/what-compelled-single-page-applications-jump-trends-katy-slemon/
  2. Micro Frontends https://martinfowler.com/articles/micro-frontends.html
  3. Web Component https://developer.mozilla.org/en-US/docs/Web/Web_Components
  4. Webpack 5 Module Federation: A game-changer in JavaScript architecture https://medium.com/swlh/webpack-5-module-federation-a-game-changer-to-javascript-architecture-bcdd30e02669
  5. Module Federation https://webpack.js.org/concepts/module-federation/
  6. Cross micro frontends communication https://dev.to/luistak/cross-micro-frontends-communication-30m3
  7. How Fast Should A Website Load & How To Speed It Up https://www.hobo-web.co.uk/your-website-design-should-load-in-4-seconds/
  8. A proposal for making AJAX crawlable https://developers.google.com/search/blog/2009/10/proposal-for-making-ajax-crawlable
  9. Angular Universal https://blog.angular-university.io/angular-universal/
  10. Angular Universal Angular & ASP.NET Core Engine https://github.com/angular/universal/blob/master/modules/aspnetcore-engine/README.md
  11. Mobile First https://developer.mozilla.org/en-US/docs/Web/Progressive_web_apps/Responsive/Mobile_first
  12. Progressive Web Applications https://developer.mozilla.org/en-US/docs/Web/Progressive_web_apps

--

--

Vladyslav Bezruchko
Inside the Tech by SoftServe

Solutions Architect at SoftServe, certified Google Cloud Architect