In “old style” web apps, routing is performed on backend. Backend knew what page is requested, knew what data needed by what page, generated html specific to that page, and included css and js needed for that page along with response.
In single HTTP request, browser gets the content requested by user.
In the single page application approach, backend serves a single catchall html page for
document.location, does routing on frontend: figures out what page is
on getting the the data, renders it in browser.
Here we take four (original html, main js, page specific js, and finally api request) http request to show content.
Of course most frontend frameworks offer a few optimizations to help solve this architectural issue.
This is an optimization by backend to try do the entire thing that browser does, on the backend, so the original HTTP request returns pre-rendered html content.
In this scheme, the entire 4 http request dance still happens on the frontend, but during that dance, end user gets to see the HTML content, potentially interact with it minimally, and finally when data is loaded, the original HTML is “hydrated”.
The hydration step is potentially dangerous, can lose user’s input, or can lead to screen “flash”.
SSR is done both to let users see something in browser sooner, and to assist crawlers like google-bot so your page can be indexed correctly.
Independent of SSR, or along with it, the API request can be avoided, if backend does routing, knows for what route, what APIs are needed, calls the API on the backend, and includes the returned data in the HTML.
To mitigate this, sites split themselves in multiple bundles, but this becomes a hard problem really fast, needing constant tweaking, maybe even machine learning. Basically how do you decide what pages to bundle together? If your decision is not good, say you bundled A and B together, not good means user went from A to C, so bundling B was useless.
rustfmtFor Some Section