MPA vs SPA

Understanding the tradeoffs between Multi-Page Application (MPA) and Single-Page Application (SPA) architecture is important to understand how island.js works and how to use it in proper way.

What are MPA and SPA ?

MPA and SPA are two different ways to build web applications.

A Multi-Page Application(MPA) is a web application that loads multiple HTML pages from server. Each page is independent of each other and has its own URL. When you click the link to navigate to another page, the browser will send a request to the server and load the new page. For example, the traditional template technology like in JSP、Python Django、PHP Laravel and so on are all MPA framework.

A Single-Page Application(SPA) is a web application that loads a single HTML page that loads in the user's browser and renders HTML locally.The page is loaded once and then dynamically updated via JavaScript as the user interacts with the app. For example, Next.js, Nuxt、CRA(create-react-app) are all SPA framework.

Fortunately, Island.js support both MPA and SPA architecture. But how do we choose between them? Let's take a look at the pros and cons of each.

Comparison

Performance

In MPA, the server will response the complete HTML page to browser, but SPA need to execute javascript to render the page. So first load performance of page in MPA is better than SPA, which is important for a content-focused website.

However, on the other hand, SPA has a better performance and experience on subsequent page loads. Because SPA only need to dynamically load the part of the page, instead of a whole page. And also, SPA won't reload the page when you navigate to another page, which is more friendly to the user.

SEO

MPA is a good choice for SEO, because each page is independent of each other, while every page has its complete HTML content, so it is easy to optimize the page for search engines.

SPA is not good for SEO, because the content is dynamically generated by JavaScript, so it is difficult for search engines to crawl the content.

Route

MPA does not need to consider the route in browser, because each page has its own URL, and the server will accept the request and dispatch it to the corresponding page.

But SPA need to import route module to handle the route in browser(e.g. base on history API), because the page is loaded once and then dynamically updated via JavaScript as the user interacts with the app.

State Management

Another complex part of SPA is state management. Because in SPA the state of the page is maintained by JavaScript and should be managed between different pages.So there are lots of state management libraries like Redux、Vuex、Mobx、Valtio and so on.In fact, sometimes it can be a little bit difficult to manage the state in SPA.

MPA is not so complex, because the state of the page is maintained by the server, and the state of the page is independent of each other, so it is not necessary to manage the state between different pages in browser.

Tradeoff

So you can see, MPA make the fast first page load performance, but SPA make the better subsequent page loads performance and experience, with the cost of more complex route and state management. Both of them cannot meet all the requirements of the project, so we need to make a tradeoff, between the performance and the complexity.

However, is there a way to combine the two ways?

The answer is yes. In fact, many framework use MPA for first page and then SPA for subsequent page loads, such as Next.js, Nuxt and so on.

How did they implement it?

Firstly, the framework will render the page on the server side(be called SSR or SSG), and then send the complete HTML page to the browser, so the first page load performance is good. It's important that the client script for SPA is injected in the HTML page at the same time. So the result is that when the page is loaded, the client script will be executed to rerender the page and manage route and state via JavaScript, as well as binding the DOM event to make the page interactive.

The so-called rerender and binging DOM event process is also called hydration.

So in a word, MPA and SPA are not mutually exclusive, we can combine them with the cost of the hydration runtime execution and the network io caused by client script.In addition, there are also some other tradeoff.

Motivation

With these cost after combining MPA and SPA, I have to say sometimes combine them is not a good choice, especially for the content-heavy website, because the hydration runtime execution and the network io caused by client script will make the first page load performance and TTI(time to interactive) worse.

So island.js recommends to use MPA for content-focused website, which is a default internal strategy. Then here comes the problem: MPA only generate static HTML page, how to ensure the hydration process if there are some interactive parts in the page?

That's the motivation of island architecture. You will find the answer in the next article: Islands Architecture