Single Page Applications (SPA) are really popular these days. And that is understandable as React, Angular and similar libraries with browser based routing make it quite easy to do so for developers. End users like SPA’s as well because navigating around is really fast. Much faster than the traditional browser-based applications that do lots of postbacks. So everyone is happy right?
Well everyone is happy if SPA’s are done right but quite often they are not
The problem with SPA’s
The problem with SPA’s is quite typical:
If a bit of something is good then more of the same must be better.
This is something that comes up with lots of things, not just with SPA’s, and it’s usually wrong.
The first reason developers notice that creating one big SPA is an issue, is when the load time of the initial page starts taking way too long. After all everything loads up front when the user first loads the application. But then they learn about Webpack bundle splitting and lazy loading and the problem seems to go away. Depending on the technology used, and the application architecture, lazy loading can be really simple. Read this blog post for an example of how to do so in Angular.
The real reason one large SPA is wrong is because of coupling. If you build your whole application as a SPA then everything is coupled together. Making a small change in one obscure part of your application could have a global effect. With different pages the chance of an accidental global change is much smaller. It can only happen if the code is actually loaded on another page.
So should we stop building SPA’s?
No, absolutely not!
But we should stop making them as big as some people are doing.
Instead, split your application into functional parts. Turn each functional part into its own SPA and use normal browser navigation to navigate between them. These SPA’s are typically called mini SPA’s as many of them together form the complete application.
How big should a mini SPA be?
That is an easy one: as big as they need to be and no bigger than that.
Which is still kind of vague of course.
In general, they should be about one piece of functionality. Or, in case you are into DDD, one bounded context is the right size.
What that means in practice is that you split your application into functional parts. Just suppose for a moment you are building a large sales application. Then you probably need to build a customer management piece. There will also be an article management part. There will be an order entry part and finally there will be an order fulfillment part of the application. In reality there will be more but as an example these four are enough. These four are quite distinct, each has it’s own job to do and end users will not likely switch between them all the time to get their job done.
Sure there is overlap. Both order entry and order fulfillment will need to use customer and article data. But the shape and form of that data will most likely be different and certainly be read only. So while they have a dependency on the data from the other parts they don’t need the actual code from the other modules to function.
This makes for a great split. Create four different mini SPA’s and have a shell application so everything feels like a single application to the end user. The navigation inside a mini SPA is really fast, it is a SPA after all. The navigation between different modules is a bit slower but far less frequent. And use of HTTP caching or, in a new browser the ServiceWorker, will even make that quite fast.
Enjoy building your mini SPA’s