Single-page applications are everywhere. Even blogs, simple html pages (in the beginning something like https://danluu.com/), have turned into big fat monsters – for example, jlongster’s blog has 1206 stars at the moment of writing, and not because of the content (people usually subscribe to blogs rather than star the source): the only reason is that once he implemented it using React & Redux. What is the problem, though? He wants, he makes it, no questions here. The problem is that it is considered normal to make blogs for reading so bloated – of course, there are some people who complain, but the general response is utterly positive. But who cares about blogs – the problem is that nowadays pretty often question is not “to SPA or not to SPA”, rather “which client-side framework should we use for our SPA”.
I am a frontend developer, who all his career was involved into creating quite complicated single-page applications (like Lebara Play, or app.contentful.com – you have to have an account to see the actual app, though) – and for a long time the question “should be a single-page application” did not exist for me: of course it should! But some time ago, at my previous job, my manager came to me asking to investigate our application size – about two years ago we migrated from WordPress to React/Redux/Immutable.js stack (which is a pretty common choice, I guess), and it turned out that average load time increased twice over this time! Alright, maybe it was just our problem, and we are not that good – so I was looking into it for a couple of weeks, and after my research I re-thought a lot in front-end development.
Nowadays a lot of startups, cool companies and personal websites are made using single-page applications – it is pretty common, and nobody is particularly surprised when they don’t see a reaload after clicking on a link inside the application.
Let’s summarize the experience, starting with the pros:
onClickhandler, and browser can’t recognize it as a link (even if the majority of the links are valid, sooner or later you’ll encounter a non-link “link”)
Back to the beginning, where I said we found that WordPress was actually faster than our new shiny stack. Our application was not the most sofisticated, but had some interactive parts – it was a financial website, where you can apply for a loan, go to your personal accout, restructure your loan, and change some personal details. Because it is financial and fully online, we had to collect a lot of data, and it was several forms with live validation, on-the-fly validation and some intrinsic flows, so it made it a perfect case for frontend. However, one problem – it was slow; as I mentioned, load time increased twice. So, I was looking into the reasons why it is so big, and is turned out, the size was basically dictated by our react ecosystem – all libraries we needed created this big chunk of js (around 350KB gzipped). Another big chunk was our actual application code – it was another 350kb, and in total we ended up with ~2.6MB non-gzipped data, which is, of course, insane. It means that no matter how optimized our code is, in order to start the application, a browser has to do several things:
You can read more on this process in Addy’s Osmani article.
At the end, my findings were that we owe this time increase to big bundle size. As I mentioned, though, our vendor chunk was half of the size, so it means that basic functionality (we had pretty “rich” homepage) would require a big chunk already, and can solve the problem only partially.
Let’s take a look at actual sizes of the applications. Usually I am logged out, and I have my adblocker enabled.
Bright engineering team, many articles about migration to React. Let’s see how is it going, on the typical page of individual place:
There are tons of files, and in total it makes it 1.3MB gzipped. Again, 1.3MB to show you a place – pictures and description. Of course, there is a lot of user interaction, but at the end of they day, as a user, I want to look at the place – also I can be logged out. Is it user-friendly? I don’t know, but I’d be happy with static content to just explore what are requirements, to read description, etc. I am pretty sure that aggressive code-splitting allows them to ship features faster, but the price here is user’s comfort and speed.
Just 3 initial files, and 1 later (I guess lazy loading):
In total 475KB + 44.5KB for some lazy-loaded file. Much better than AirBnB, but still, a lot of stuff, just to show you feed. There is also a mobile version, which feels much lighter, but the size is actually similar.
Medium is a cool platform for blogs. So, essentially, it is an advanced place for texts, similar to one you are reading right now. Let’s open an article, which I mentioned before, about cost of JS:
Also 3 files:
In total 542KB, just to read an article. You can read it without JS at all, by the way, so it means that it is not that crucial for the main task.
All these websites I’ve mentioned load on my latest 15” MBP with stable internet connection for 2–3 seconds, and become fully usable after another 2 seconds, which is not that bad nowadays. The problem is how normal it has become over the last decade – slack has 0.5s delay between clicking and switching to the channel, and we don’t even notice it anymore.
Don’t take this rant as an attack on the SPAs itself – I like them (at the end of the day, I write one for my day job!), and they allow to create very powerful user experience, which works across all platforms. However, a lot of things I was working on as a SPA, in fact should not be one. For example, some time ago I’ve made a portfolio website to my wife, and of course I did using cool SPA stack – but in fact, it is just a blog with a lot of images and couple of widgets; so I’m guilty of this trend more than many.
Also, feel free to take a look at the first CERN website. Just compare navigation speed when you are on this website, and the responsiveness, when you are leaving it to some external, modern one.