Don’t assume that a good developer experience necessarily equates to a better user experience
This article was written by our guest author, Stuart Langridge.
If you're building websites, you've confronted the question: where should the work happen? Client-side or server-side? This is the latest iteration of one of the Big Questions of Computing: keep everything in one place for efficiency or push it all out to the edges for power?
As ever, the answer is a little of both, but right now this pendulum has swung further in the direction of the client than it should do. Current trends are for a website to do almost all its work on the client, and to be dependent on a JavaScript framework to do anything at all.
This trend has become almost standard practice in some areas: "we build sites in React" (or Vue, or whatever your choice of framework) is an automatic response. But the wise developer uses the correct tools for the job. If the only tool you have is your client-side framework then everything may well look like a nail, but it's worth learning a little more about what else is available.
How you understand what the correct tools are is the important point, of course. That’s what we are here for today.
Developer Experience – the “DX”
Building websites mostly or entirely client-side has some benefits. It's a good developer experience, where:
- You can write code as if it will run on a theoretical perfect browser with no bugs, where everything works well ahead of the web standards documents.
- There is a library of existing components to draw on built by somebody else.
- All you have to do is write in one language, JavaScript.
- Your tooling takes care of managing the mismatch between this shiny world to build for and the grubby actuality of cross-browser, cross-platform coding with all its bugs, imperfections, and the three languages of JavaScript, HTML, and CSS.
A good developer experience (the "DX") is, indeed, valuable. If it’s easier to build sites, more sites get built, and at a faster pace. So goes the argument.
Where this argument errs is in assuming that a good developer experience necessarily equates to a better user experience.
Sites are not built for the developers' benefit; they are built for the user. There is an ongoing myth in the web development community that a site which is better built is also better used, almost by definition, and that isn’t correct.
Impact of client-side
The median weight of mobile sites has gone from a few tens of bytes of JavaScript in 2011 to half a megabyte today. That unpacks to over two megabytes of script once it's in the browser. If any of the JavaScript fails (which sometimes it will), then that leads to brittleness and delay where nothing works. And even if it does, the user experience is a site which is slow to load, slow to react, and slow to do anything.
The costs are not the same, either: Zach Leatherman showed that. The browser can cope with lots of HTML much, much more easily than with lots (or even not all that much) JavaScript.
This is a long-standing issue, and it’s steadily getting worse. Back in 2013, we were already searching for the world’s heaviest mobile website and the need to focus on all this has not changed. What has changed is that we have better metrics now than we did then.
The Core Web Vitals scores, which can be calculated by Lighthouse with PageSpeed Insights, include First Input Delay and Largest Contentful Paint. These are real-world performance indicators: how long does your site take to display its main part on the screen?
A page should be mostly loaded and displayed in 2.5 seconds. It should be interactive in 100 milliseconds. Putting up a loading spinner for ten seconds while the site downloads two megabytes of script does not count; that's a bad user experience, no matter how good the developer experience was when making it. DX does not equal UX.
This is something we think about a lot at 51Degrees. We practice what we preach by ensuring our website has a good user experience – one way we measure this is by ensuring we score 100 on PageSpeed Insights for both mobile and desktop devices.
Energy usage
It’s sometimes useful to consider the web as being a huge distributed computer. If you’re building an application that a million people will use, that can have quite imposing server requirements. But outsourcing most of the work to those million people saves you having to provide the server resources for it.
However, while this might be good for your web server resource budget, it isn’t good for the overall energy budget. If you run code in a user’s browser, and you have a million users, then you run that code a million times.
At some point, we need to consider sustainability as part of our plans. We’ve already looked at the environmental impact that universal encryption has; how many cups of tea (from boiling the water) does it take to have your web app do most of its work once per user instead of just once?
Technology mismatch
As developers, we tend to value technology and the web more highly than our users do, which means that we have more discretionary income for it. Building on a high-end Windows or Mac laptop and testing on the latest iPhone or Pixel with lots of RAM and CPU gives an actively misleading impression of what a site is like. Most people using the site will not be on the latest devices or the strongest technology.
It can be very illustrative to try a site on a medium-spec Android device. Better yet, a lower-spec one. It's worth looking at your analytics, especially if you're tracking detailed device capabilities and statistics (the 51Degrees PriceBand device property is your friend here), to see what the lowest 25% of your userbase are using and to try that out for yourself.
Browser development tools have facilities to simulate older CPUs and to throttle performance and networking, but there is no substitute for obtaining a cheap Android phone and experiencing how your users see your site.
Going server-side
So how does going server-side help? Well, the process of splitting processing between the server and the client is to outsource some of the CPU requirement from your server to your users' devices.
This is useful – it reduces the amount of time and effort your server needs, which you pay for, but the users' devices can't always cope with it. You can vary the specification of your server as you choose, and if you're deploying in the cloud, you can scale that up and down at will, balancing costs with user experience in the way that best suits you. This is both simpler and cheaper than buying all your users the latest iPhone to browse with, as well as being actually possible!
Server-side resources are also first-party as far as the browser is concerned. While it is useful to be able to fetch data and resources from the client, there are complexities and security issues with that which do not apply on the server where the code is under your control and inside your security boundary and inaccessible to others.
You are also able to work in your language of choice. Sometimes it may seem as though all web development is necessarily in JavaScript first, last, and always, but this is very much not the case. Broadening your horizons may lead you to Django, Laravel, or even Deno if JavaScript is still your preferred option.
Take "Which Three Birdies?" as an example; when we built that, we asked ourselves the question: is there a reason to develop this as a client-side single-page JavaScript-dependent app? And there wasn't, so we didn't.
Interacting with the third-party APIs was easier on the server. We're able to take advantage of caching and the database for storage; the site is automatically quicker to render and more available to more people.
Now, there can be times when you do want to consider client-side deployments. Using client-side JavaScript is not, at all, a bad thing – you can develop server-side, for the reasons already discussed, and enhance the user experience with client-side JavaScript as much as you want (and you should indeed do that).
Progressively enhancing a website to provide better user experience is an unambiguous good thing. What becomes more of a problem is when that client-side JavaScript is a requirement rather than an enhancement.
In some situations, it cannot sensibly be avoided: if you need to use client-side device APIs, for example, there's no real substitute for making the site dependent on JavaScript because there's nothing to do without it. There is also a wealth of useful components which can be delivered client-side which will improve the user experience and are rather clunky without JavaScript. Think of reordering a list by drag and drop, for example.
However, be aware that such enhanced interactivity can also come with accessibility concerns and providing a server-side fallback using native browser controls can be a useful approach as a fully accessible way to still access your content.
In the end, there may be situations where the experience you need to deliver cannot be sensibly delivered server-side; these things do happen. But they are much rarer than may be initially considered. If you're building a fully functional client-side video editing suite then yes, it's reasonable to depend on JavaScript. A site storing per-user data in a back-end database, maybe not. A site composed of essentially static data, almost certainly not.
Where your system falls in this depends on your business decisions, but it is important to consider all perspectives. Ask whether you need that client-side work, not whether you don't. The web server is the foundation of the web.
Moving back to rendering server-side will not only likely improve your performance and the energy efficiency of your web properties, but it also makes your services more available to more people more of the time. You don’t have to stop using any of the frameworks your team prefers for building. It can improve things for your users, for your team, for your business, and for the world. Give it some thought next time you’re confronted with the client-side vs server-side debate.