In order to start, single-page apps (SPA) have to download lots of assets to the client: JS files with the app itself, CSS files with styles, images, media, and so on. It is impossible to develop a large-scale JS app without any kind of modularization, so most JS apps consist of numerous small JS files (the modules mentioned before). CSS files are also usually separated by some criteria: per component, per page, and so on.
The nature of SPAs forces them to have heavy API traffic. Basically, any user action that has to be persisted requires an API call. Pulling data from persistent storage also requires API calls. By persistent storage, here I mean the database or any other similar service that can be accessed from many different devices/browsers and will store this data for long periods of time.
Both of these aspects bring us to the most terrible SPA performance issue: large initial load time. There have been studies that clearly show the correlation between the load time and page views, conversion, and other vital metrics. On average, customers leave the page if it fails to load within 2-3 seconds.
Another big issue is search engine optimization (SEO). Search engines tend to give higher ranks to pages that load quicker. Plus, only recently have crawlers learned how to parse and crawl SPAs properly.
How do we deal with this?
Assume we have found a good balance between initial chunk and on-demand chunks. We have applied compression and good cache strategies, but still there is an API layer that also has to be optimized for initial load.
Potentially, we can combine all API requests in one huge request and load it. But different pages need different data, so we can't create a request that will fit all. Also, some of the data requires client-side processing before we can make a subsequent request for more data. Modern API techniques such as GraphQL allow us to solve the problem in one way, and we will talk about this later in the book, but this still does not address the issue with not-so-smart search engine crawlers.
Sad? Yes. There is a solution for that though. It is called server-side rendering.