Micro frontends

What can you do on sportsbet.io?

  • Login via password
  • Register via password
  • Login via social
  • Register via social
  • Forgot password
  • Notifications
  • Edit profile
  • Manage preferences
  • Marketing
  • Manage password
  • Manage security
  • Verify account
  • Deposit (24 currencies)
  • Withdraw (24 currencies)
  • BTCXE
  • Transfer funds
  • Search
  • Promotions
  • Help central
  • Live chat
  • Support pages
  • News pages
  • Fraud detection
  • Analytics
  • Casino
  • Sports pages
  • Event pages
  • Betslip
  • Free bets + Bet boosts

Quite a bit actually, but what is the problem?

History

We started as a single page application, which means:

  • On any page load, we ship a bunch of Javascript code to the browser.
  • This javascript code takes over and renders a UI. 
  • If the user navigates around the site, the javascript code handles navigation/url changes and only fetches data from an API to update the UI. 

Expectation is that we're super fast and the customer experience is great

SPAs are Network/CPU bound

  • We bundle megabytes of Javascript code into a bunch of .js files and we ship it over the network to the client.
  • The browser reads, parses and executes all of this code. The customer doesn't see anything before this process has finished. The more lower end the device, the worse the experience is for the customer. They have to experience this before they get to actually use the site.

Codesplitting solves everything!

Codesplitting is the technique of loading code as the user requires it. So if you navigate to the homepage, you only get code required for this homepage and navigating to another page loads more code.

Hint

Server Side Rendering

This is the technique of executing your client side code on the server and pushing not just Javascript to the client but actual HTML.

  • Customer visually sees the page before Javascript has been parsed / executed - way faster.
  • SEO friendly pages.
  • Pretty exhaustive process CPU wise.
  • DDoS multiplier (server executes all client side API requests on the server, so 1 GET call results in 10+ API calls)

Hint

So SSR + Code splitting solves everything?

What we call a Single Page Application is actually a monolith and shares the same problems

  • Application is too large and complex to fully understand and make changes fast and correctly.
  • The size of the application can slow down the build / start-up / deployment time.
  • You must redeploy the entire application on each update.
  • Impact of a change is usually not very well understood which leads to do extensive manual testing.
  • Continuous deployment is difficult.
  • Monolithic applications can also be difficult to scale when different modules have conflicting resource requirements.
  • Another problem with monolithic applications is reliability. Bug in any module (e.g. memory leak) can potentially bring down the entire process. Moreover, since all instances of the application are identical, that bug will impact the availability of the entire application.
  • Monolithic applications has a barrier to adopting new technologies. Since changes in frameworks or languages will affect an entire application it is extremely expensive in both time and cost.

Problems we faced with Monolith + Code splitting + SSR

  • Really hard to maintain
  • Easily broken
  • Domain knowledge has to be very vast, you need to know about everything.
  • Testing takes forever because you have no distinct separations - it's all a single system.
  • Even with code splitting it still generates a huge amount of code
  • SSR cripples CPU servers on huge loads

Solution

Microservices frontends

  • Single focus SPAs
  • With code splitting
  • With server side rendering

also known as portals

Nginx proxies all requests to different SPA - think of it as an API gateway

Each SPA has its own specific set of business logic. Each can be independently built, deployed, scaled, tested. Can even build teams around these if they grow too big.

Flawless victory!

New problems appear!

  • Maintain consistency in design across multiple applications
    • Build a design system!
  • Lots of code is duplicated across these applications
    • Maintain a separate client library that is re-usable across all applications.
    • Maintain a separate server library that is re-usable across all applications.

But the benefits outweigh the new challenges by a lot in my opinion. Things are in general more manageable and easier to change.