Transcript
This transcript was autogenerated. To make changes, submit a PR.
Hi everyone, my name is Alexander Gozenka, and today
I'm going to talk about front end architecture,
in particular about splitting the monolith.
But before we start, just a few words about myself.
I have more than seven years of commercial
experience in front end development.
Now I lead the development of a large fintech application.
And recently I started talking about architecture,
front end architecture. And of course this is a
really complex these. So it needs to reveal step by
step. So today I'm going to talk about
problems of monoliths applications.
Or maybe monolithic application doesn't have problems. So we'll talk
about it today. Then I'll
show you six ways how you can split your
monolith to reduce complexity of your
application, to make it more modular.
And after that we will summarize and find out
when which method is best to use.
So let's start.
First of all, we need to understand the
difference between two approaches,
monolithic and microservices. When you
use monoliths architecture, you are
using a single module that works autonomously
independent of other application. For example, you have to
do list. And in
web page you will show only this to do list,
this to do list stored in its
own repo and deployed by
its own. So this is a single module.
Microservices approach is when you have
several independent from each other, small low
couplet and easily modified module.
Just imagine the same to do list.
But at these web page you also have
footer and header, and footer
and header is independent application, so we can
deploy it independently of each
other. So this is microservices approach and
one of the main questions of this speech
monolith is it bad or no? To answer
on this question, let's take
a look at this chart. On the x axis
we have the lines of code which represents the size
and complexity of our project. On the
y axis we see these cost to line.
This is development and maintenance. It means
not just initial cost of writing line of code,
but also maintaining it, updating it,
and ensuring it remains functional and efficient in
our growing application. Now,
there are two distinct curves here.
The blue curve is microservices.
This starts relatively flat, but begins
to rise gradually as lines of code increase.
In the early stages of these project, its cost might be
higher due to the setup required for
individual services. However, as the projects grow,
the cost increases only gradually.
This is because with microservices we can isolate
problems, scale services independently and
deploy them separately so complexity
doesn't increase dramatically.
The yellow curve is monolithic approach.
Initially, it's pretty cost effective.
Everything is in one place
and it's easy to manage.
But as the lines of code increase, you can
see a sharp uptick in the cost.
This emblematic of these challenges in scaling
and maintaining these monolithic application. As it grows,
every change impacts these entire
system, making it increasingly challenging
to manage and update. In summary,
while monoliths architecture might seem cost
effective for small and medium projects, as application
grows, the benefits of microservices architecture
become apparent in terms of
both development and maintenance cost.
So what we can see from this chart
in summary, first point, monolith is not
bad. It's a really good decision when you have small or medium application.
And second, monolith is not bad until
a certain point. And there is another
main question, how to recognize this point
after which microservices will be
cost effective.
To say the truth, it's a really subjective
feeling, but I have four main
triggers to recognize it.
First one, it's long
builds and CI pipelines. For example,
your CI pipelines needs several hours,
for example 6 hours, it's too much.
Second one, it's rapidly increasing code base complexity.
And because of this breaking project
entry threshold, for example, when you
can efficiently onboard on your project
only senior developers,
it's like a call. And last one
when more than five people working on the project.
This is the most subjective point because I know a project when
for example 15 people working with it and
it's a really good in monolithic approach.
But over time this value may increase.
And just imagine you found
all this trigger in your application and you decide to
reduce your code complexity to split
your monolith. How you can do it?
Let's take a look at first way
and it is iframe.
It is the oldest and the most time tested method.
It was released in 1997 and
it's kind of first implementation of front end microservices
from the last century and now doesn't
lose revelance. Especially useful on simple sites.
For example landing page when you need to
embed some modules, for example maps.
Next way is using Nginx or another proxy
server. This is the most controversial and nonobvious
way it is implemented. Simply some
pages of your application will be laid on a
separate bundle with the help of
proxy server and load it as a separate application.
Of course there are many disadvantages here.
There are drawdowns in performance, we load
entire bundle again and again. These main advantages
of single page application, we just lose it and
code duplication and something more. But there
are cases when this approach makes sense to use.
For example when you move from one
framework to another, the old pages will be within old
application and one and
new pages with new application within
another. Over time the old application will lose pages
and the new one, on the contrary, will increase until the
only one remains. Third way is using
web components. This is a very
interesting tool that allow us native
use of the component approach.
On this slide you can see an example of
using web components and it's very similar
to class components in react, doesn't it?
Of course there have many advantages like full
encapsulation of styles and logic,
native browser support and cross platform.
You can create only one web component and using
it inside react angular view
applications. But why
didn't it get popular? Because we
use react angular libraries
and frameworks not only because of the component
approach, but also because of their APIs like decorators,
hooks, context, et cetera.
Moreover, popular frameworks have a large infrastructure and
a wide market penetration.
Next way to split your monolith is using NPM,
not package manager. This method is
the most common and in most cases
it is the best for you. This approach is ideal
as a first step before using
micro frontends. That is,
you can first split application into several NPM packages
and these turn these packages into
independent frontends or micro front ends.
With advantages I can say
of NPM, it's disadvantages,
sorry, difficult to debugging.
Just imagine you want to lock and console
some value from your NPM package.
To do it you need to add your code,
create a build of this package, substitute this build in the
host package, run host package, host application and
only after that you can see your
output in console. Also it's
complication of the release cycle. For example,
you just need firstly to release
your NPM package. After that
you upgrade these version in your host package in
your host application and only after that you can deploy
your host application. But there are
many pros. There are many advantages of using node
packet manager NPM like
ease of implementation, versioning and pipeline
acceleration. You just don't need to
run all tests in your every
NPM package when you deploy your host
application. The last two methods
are realization of micro front ends.
The conception of micro frontends is shown on
these screen.
It's when you can use different
application inside a host one.
And this different application may be written
on different frameworks using different libraries
and deployed independently. So single
spa or single spa, it's a kind
of realization of micro front ends and this
approach has several peculiarities.
First, one single spy has a container
within which we register application and
can use them as a separate independent application within a
single page. It also allows
us to use application lifecycle method like loaded
mount unmount.
And it also allows us to
set a config that will control which rotors,
which applications should be loaded on.
And the last one is
webpack five module Federation.
You can use this method only
within webpack five. Even you are using webpack
four on your project you couldn't use modal
Federation plugin, so these is you should
to know before choosing this way.
Also using modal federation you can
cache libraries so you don't need to load.
For example react ten times. If you
use ten react application, each application
has its own entry point in which we
say what it exports. It's like a realization
of public API which is a really good
design pattern. Unlike a single
spot. It allows us to
use not only the entire application but also
its modules. For example,
you can use only selectors from
another applications, not whole application, only selectors.
And let's summarize all these six ways
to split your monolith and
where you can choose each other.
Choose them let's start with iframe.
IFrame is really good when you need to
embed a model into a site without using heavy frameworks.
For example to embed maps,
map model module on your landing
or composition of several simple application.
For example, you have independent sidebar
with several links and you
can use just iframe tag to
embed it on your application. Even if your application
is really complex.
Proxy server is good in transition period
from one framework to another if
you don't want to bother with micro front end
and you're ready to sacrifice performance
in a short of time. Web components
are good for you if you
don't have binding to the infrastructure of any framework
or you
want to make a cross platform components,
for example UI kit for entire company.
NPM is a great decision
if you want to reduce your code base and you don't
want to bother with micro frontends.
And what about micro frontends single spa? It's a
good decision when you need to combine
several application on different frameworks or
you want to get involved in the application lifecycle
like mounted, unmounted, loaded and et cetera.
Or you want to link application to a specific Ural.
For example on itone ural we load this application,
on another ural URL we
load another application and the last method
is using code federation in webpack five.
This is great decision when you want to
optimize the bundle size. For example, do not load
or react for every application.
If your application uses react and you use
webpack five. So that's all for now.
I hope this information will help you write
efficient and maintainable code.
And have a good day.