Sadly, this is probably where the core of the problem lies. "It makes code more readable and intuitive" is NOT the end goal. Making your job easier or more convenient is not the end goal. Making a good product for the user is! Software has got to be the only engineering discipline where people think it's acceptable to compromise the user experience for the sake of their convenience! I don't want to think to closely about data structures, I'll just use a list for everything: the users will eat the slowdown, because it makes my program easier to maintain. I want to program a server in a scripting language, it's easier for me: the users will eat the slowdown and the company budget will eat the inefficiency. And so on.
This is a very limited perspective. Let me give you an enterprise software perspective:
1) Software maintenance costs. Better maintainable software allows more services to be delivered with a smaller budget.
2) Software is never finished. Ability to respond to new or changing user requirements matters to users and is perceived as part of the quality of service.
3) Software is going to be maintained by someone else. If they can not maintain it then users have to go through another iteration done by another team (best practice: fewer features, but at least the implemented features have more bugs).
Better is not the same as easier. This is such an equivocation fallacy since both of those terms are highly subjective. Maintenance costs are measured in numbers and not some imaginary developer ideal of job security.
Like, most of these people are not saying, "we could do this thing which would speed up the app by an order of magnitude, but we won't because it will decrease readability." They have no idea why their code is slow. Many don't even realise it is slow.
My favourite talking point is to remind people that GTA V can simulate & render an entire game world 60 times per second, 144 times on the right monitor. Is that a more complex render than Twitter?
Computers are really fast, it doesn't take garbage code to exploit that.
Different business models result in different environments in which to conduct software engineering; different constraints and requirements.
IMHO constant and unpredictable change (which I assume happens less for games like GTA) is one of the big differences, as is the relationship between application performance and profit.
But I like what you’re saying and would love to see that world.
Is the difference because GTA has more "readable" code?
I have other games that do load up quicker than Twitter, which I do think is damning, but it's not really the point I'm trying to get across here.
But then, you brought up GTA and games, which aren't even apples and oranges with a website. Websites—even the Twitter website—don't require GPUs or dedicated memory, they don't have the advantage of pulling everything from the local hard drive, and yet they actually work as designed, not merely in a low-resolution, low-effects mode on computers more than a couple years old.
And while I wouldn't point out the Twitter home page as remotely fast for a web site, have you actually even looked at it recently? It shows a lot more than just a few tweets and avatars. It's got images, embedded video, etc.
There's definitely another discussion to be had about why web tech is so disastrously slow given what computers are capable of, but it's not worth having here. We're never going to settle that one, and regardless if you are a web guy, you're stuck with JS.
>It's got images, embedded video, etc.
Bad excuse IMO. Lazy load them.
That being said, I don't think it addresses the problems with client side applications, although it may allow more complex ones.
B: "Nutritious, healthy food will ensure the longevity of my customers, thereby maximizing lifetime customer revenue."
Then I refreshed the page and it still took 10 seconds to reload.
I'm sure their code is also relatively bug free.
Making your code "more intuitive" does not result in a better product. Making a better product does. The argument is that software development is one of the few jobs where the employees' experience seems to be equal or more important than the client experience. Sacrificing a restaurant goer's experience (taste) because it makes the restauranteur's experience (customer LTV) better is a decent analogy.
B: "As long as you enjoy it, and we can keep making it for you at the same quality you enjoy, we don't care how inefficient our kitchen is".
Because the universal rule is that 90% of everything is terrible, including software. Corollary rule is that work expands to fill all available time, and software expands to fill all available resources.
If you go back to before the ascent of age of front-end frameworks, you would find that there were still tons of sites that were slow and poorly performing, despite running entirely in server-side technologies.
Something that made Google incredibly appealing when it first came out was it’s instantly-loading front page with a single search box and a single button. This was in drastic, shocking contrast in the age where every other search engine portal had a ton of content on it, including news, stock tickers, and the kitchen sink.
In the end, unless the developers of the sites make performance a priority, it makes absolutely no difference what the tech stack is. The problem is that companies don’t prioritize it.
Maintainable code can quickly and easily be extended into new features for the customer.
Unmaintainable code usually results in a ton of support tickets and late nights hunting and fixing bugs that originated from deploying into production that day. This leads to heartache and frustration for the customer.
The customer comes first, yes. Good maintainable code, is a way to achieve this goal.
I have done both in heavy server side rendering using templates and SPA rendering on the client side. It all comes down to your user base and the devices/browser they are using, if they have an aversion toward running JS in the browser.
By using JS on the server side, you can maintain quite bit of logic on both server and client side. If you are doing web development, why not make it the same. Yes, one shall not trust the client validation, but many people find JS validation to be more user friendly than a form submit.
Blunt example, however that is what matters to a customer that just commissioned a web site for pizza delivery.
But it does hinge on how good the delivery website is though. If you haven't been to a pizza website in the past 10 years, let me point out they are complex with interactive drag-and-drop build-your-own-pizza wizards. Better client-side tech helps build those features to sell more pizzas.
How does your envisioned alternative help sell more pizzas than the heavy-client approach that pizza corporations have decided on?
Really? Because personally I find I tend to do more business with places that have interfaces that don't make me want to beat the developer with a wrench.
But to answer your question, if you write clean code then when that company expands it’s operations it is easier for you (or whoever next gets commissioned) to later expand on that site to add more restaurants, thus then allowing your customer to sell more pizzas.
You’re right it doesn’t but I thought the context had drifted from that topic and onto code quality.
If we’re talking strictly about JS heavy sites then I’m definitely in favour of the less is more approach. There’s times when it makes sense having JavaScript trigger restful APIs rather than have the entire site rendered on the server side. The problem is JavaScript often gets overused these days.
I could write an essay on where I think modern tech has gone off the rails though.
> if you now want to pick on my example.
That’s a strange comment to make considering you presented the example for discussion. Of course people will then “pick on” the example, in fact you’d be the first to moan about a straw man argument if people cited a different example.
Propensity to change is one of the most common features I've found in software projects I've worked on in my career and most software engineering "best practices", as conceived by the authors of opinions about these things, are usually strategies for managing rapid change. i.e. structuring code so it's amenable to change, understandable to the maintainer who inherits your code, has guardrails around important invariants and guarantees via assertions and tests, etc.
The details of how (and to what degree) these things should be done are highly contextually sensitive, and that is where the dogma of "best practices" can start to interfere with creating a good user experience. But I find it a little eye-rolling when people talk about hygienic software development practices and user experience as though they are in opposition. Tests, legible code, flexible structure, etc. are enablers of good user experience, because they're what allow us to change products to fit the needs of our users. They're what allow us to ship things that people can use without them exploding.
The tendency toward asset bloat on the web and just the general use of cheap-in-development-costly-for-the-user solutions (scripting languages, inefficient data structures, verbose serialization formats, piles of dependencies) is definitely an industry problem, but I think its naive to attribute these decisions to lazy devs or devs trying to make their jobs more convenient. In my experience there's two common causes for this state of things:
1. In all seriousness, the nature of capitalism. In reality, most businesses don't actually care about the majority of prospective users. They care about a couple narrow segments of users, and if those users happen to be equipped with hardware to handle this kind of inefficiency (i.e. if they're first world clients on desktop or high end mobile devices with 4G access), the business largely doesn't care. Responsiveness, low resources consumption, low energy impact, etc. are fungible engineering goals if they don't negatively affect your sales objectives.
2. The org hasn't figured out how to incentivize responsiveness, low resource utilization, etc. as objectives. Software developers get requests to focus their efforts on all different manner of criteria, and the without designing incentivization schemes and feedback loops that orient toward these objectives, there is no particular reason why they'll be inclined towards them.
"Premature optimization is the root of all evil." You often should use a list until you've identified a specific performance issue. The list isn't the problem. Not actually optimizing is.
Identifying a JS performance issue is something that almost no company ever does unless revenue is obviously threatened (and even then many fail to act). So IMO it pays off to do a little bit of premature optimization in JS land.
I think the end goal is more about balancing the value you can create with the budget you have. It's an optimization problem.
If I can deliver 80% of the value for 20% of the price, I will do that.
Another example: I absolutely hate Amazon Prime Video for its UX and bugs they didn't fix for years (like asynchronous audio). So even though Prime is significantly cheaper in Germany, I rather pay for the more expensive Netflix instead.
Imagine all restaurants and cooks in the city decide that from tomorrow they want to make their job easier so they will drop ingredients, hygiene and processing quality with 80% so they will work less and make more profits. The ones that won't follow the new way will be put out of business because they will have more expenses and the lazy ones can put some of the new profits evangelizing the new ways making it look cool.
Quite a different scenario than all websites taking an extra few seconds to load.
In fact there's very little a website can even do to turn off customers like a restaurant can. Imagine if HN took 10 seconds to load. Who cares? There's no "HN across the street" that I can go to that hinges on a 10 second wait time.
Except of course it’s not the workers but the business decision-makers plus economic environment/pressures that make the decision.
It’s just a different business model. Less value, less expensive, higher volume. More value, more expensive, lower volume.
In your example, one of the restaurants become McDonalds and another becomes a gourmet restaurant. They compete differently.
My issue is that you can market some cheap food like "our food is cheap but good enough, come here to save money" where with software is "our software is slow,buggy,eats your battery - use it because we are lazy and we want to use latest coolest language to put on our CV".
Sure when I do a proof of concept toy project I will be lazy and use whatever I like, if I share it it will be free = I have a problem with big projects say a news site that has millions of users and your laziness(or using latest cool stuff) affects such a giant number of people.
Sure, they might get displaced by a competitor in the future - but by then they’ve probably got a large user base and a warchest to compete with. Slack is a great example of this.
If it’s software that’s life critical, then maybe, but that’s a small minority.
Markets and buyer preferences are always changing - I think it’s better to be agile (ie high developer velocity with talented product managers) to be able to detect and capture these shifts.
Polishing RipCord so it looked indistinguishable from the Slack client wouldn't be that expensive. I would argue its much more "they don't know how" than "they are making a business decision not to."
Additionally I feel like there was an implication that in such a setup the client would be doing hard processing - i.e. aggregating a raw data set on the fly - I've seen this done and it's terrible in most circumstances and it certainly isn't the norm. The server can do the heavy lifting and then hand things off to the client to do all the minor display adjustments like localization, adjusting for timezones - display stuff.
A well written front-end can provide a far more responsive page by using over-fold only rendering that the server is mostly ignorant of. Both sides of the product should be independent systems setup to treat the other as foreign I/O pipe where data is just being requested and returned.
I have seen phrases like that being used to (over)sell something so many times that I feel suspicious and doubtful whenever I see them --- Enterprise Java™ is sold using similar verbiage, and yet I'd never want to work with it again. Some of the worst codebase I've worked with --- ridiculously indirect and abstracted --- were created and described with such terms.
I'll take spaghetti code over whatever dogmatically following "best" practices produces. The former "flows", while the latter "jumps".
I can honestly say the same about every large SPA style app I've worked on and I've worked on several. Rewrites are the norm in the JavaScript arena because code devolves into a complicated mess then people look at it and say "It's just a JS app–there's no reason it should be this complicated!" Then they rewrite it with the latest framework magic, rinse, and repeat.
EDIT: I have to go further and (respectfully) say this comment I'm replying to is a load of BS. It's responding to a big pile of data saying that pageload speeds are not faster today with 'well that's not my experience.'
The other aspect of this comment that sets me off is what I'll call the "you don't have to use JSX to use React" type rebuttal. With this type of rebuttal, you respond to complaints about the way 99% of people use JavaScript by claiming that it's not strictly necessary to do it that way, despite the fact that "that way" is how everyone does use JS as well as the way thought-leaders & framework authors suggest you use it. It's responding to real-world conditions in workplaces with a hypothetical-world where JS is used differently than it is today.
This type of argument always shifts the blame on to individual developers for "using JS wrong." When 90+% of people are "using the tool wrong" there is a problem with the tool and it's not reasonable to shift the blame to every user who's trying to follow the latest "best practices."
I wish we could acknowledge the facts of the JS ecosystem (like those presented in this article) rather than deflect with "not all JavaScript apps..." when mostly what you're talking about is demos & contrived speedtests, not real-world applications.
If 'ifs' and 'ands' were pots and pans, we'd have no need for a tinker.
We also recognize that by constraining some aspects of what we are willing to support on the UI that we get profound productivity gains.
Hypothetically, if we wanted some animations in our server-side blazor apps, we could add some new methods to our JS interop shim for explicitly requesting animation of specific element ids. We could also conditionally adjust the CSS stylesheets or classes on elements for animations on round trips of client-triggered events. Putting an @if(...){} around a CSS rule is a perfectly reasonable way to get the client to do what you want when you want. In this model the client has absolutely zero business state. When you go all-in with server-side it means you always have a perfect picture of client state from the server's perspective, so you can reliably engage in this kind of logic.
There are compromises that have to be made. The above is not a perfect solution for all use cases. But, it does demonstrate that with some clever engineering and new ways of thinking about problems that we can get really close to meeting in the middle of several ideal philosophies all at the same time.
This reads like vague marketing speak. In reality SPA/front end JS frameworks do the exact opposite - violates all kinds of software best practices like duplicating logic server/client, creating brittle tests, conflation of concerns, etc, etc. SPA's front end JS frameworks are an anti-pattern, imo.
- iOS speaks to your JSON server.
- Android speaks to your JSON server.
- CLI speaks to your JSON server.
- Desktop GUI speaks to your JSON server.
- Other machines speak to your JSON server.
Meanwhile...
- Browsers use browser-specific html endpoints to utilize a historical quirk where they render UI markup sent over the wire that the server has to generate, and now you're dealing with UI concerns on both the server and webclient instead of just dealing with biz-logic and data and the server.
I find it very hard to see how this is somehow what avoids duplicating logic on server/client and conflating concerns.
Have you tried building an app with a more modern framework, like Phoenix or Blazor? You won't even need to write a single line of javascript. All business logic is on the server (no duplication of models) an can be easily testable.
In my experience, SPAs tend to get overly complex, and they mix (and duplicate) business logic with UI logic.
And yet, here we are, with a complete article devoted to the opposite effect.
Beyond that, most websites are not webapps, most are serving up static or near-static content so most websites shouldn't be designed and engineered like they are complex webapps that are doing heavy data processing.
So much of web tooling seems to aim to perpetuate the conceptual model of the web instead of daring to improve on it. Declarative views, for instance, are a breath of fresh air: instead of trying to put a JS/Python/Ruby coat of paint on the same ideas of what a web app should be, they aimed at trying to reduce a view to its essential complexity.
In a sense, being too in love with the web keeps you at a local maximum because you think web programming should be HTML/CSS/JS only.
This doesn’t need to be the case though. There have always been server-side frameworks which generate the client-side parts for you automatically, so you can mostly avoid writing any javascript even for the interactive parts. Check out rails/turbolinks/stimulusjs (used to build basecamp and hey.com) or the TALL stack (increasingly popular in the php community) for modern day examples.
Let them experience the pain of rebuilding that old wheel :)
Then there was the fact that state lived on both the client and the server and could (would...) easily get out of sync leading to a crappy user experience, or even lost data.
Oh and web apps of the era were slow. Like, dog slow. However bloated and crappy the reddit app is, the old Slashdot site was slower, even on broadband.
> They add a ton of tech debt and degrade the UX.
They remove a huge portion of the tech stack, no longer do you have a backend managing data, a back end generating HTML+JS, and a front end that is JS.
Does no one remember that JQuery was used IN ADDITION TO server side rendering?
And for what its worth, modern frameworks like React are not that large. A fully featured complex SPA with fancy effects, animations, and live DB connections with real time state updates can weigh in at under a megabyte.
Time to first paint is another concern, but that is a much more complicated issue.
If people want to complain about anything I'd say complain about ads. The SINGLE 500KB bundle being streamed down from the main page isn't taking 5 seconds to load. (And good sites will split the bundle up into parts and prioritize delivering the code that is needed for initial first use, so however long 100KB takes to transfer nowadays),
Just those that attempted to realize every minuscule client side UI change by performing full page server side rendering. Which admittedly were quite a few, but by far all of them.
The better ones were those that struck a good balance between doing stuff on the server and on the client, and those were blazingly fast. This very site, HN, would probably qualify as one of those, albeit a functionally simple example.
SPAs are just a capitulation in the face of the task to strike this balance. That doesn't mean that it is necessarily the wrong path - if the ideal balance for a particular use case would be very client side heavy (think a web image editor application) then the availability of robust SPA frameworks is a godsend.
However, that does not mean it would be a good idea to apply the SPA approach to other cases in which the ideal balance would be to do much more on the server side - which in my opinion applies to most of the "classic" types of websites that we are used to since the early days, like bulletin boards, for example.
Which reddit app are you talking about, the redesign or old.reddit.com? I ask because the old version of reddit itself certainly wasn't slow on the user side, iirc reddit moved to the new SPA because their code on the server side was nigh unmaintanable and slow because of bad practices of the time.
> Time to first paint is another concern, but that is a much more complicated issue.
That's the thing though, with static sites where JQuery is used only on updates to your data, the initial rendering is fast. Browsers are really good at rendering static content, whereas predicting what JS is going to do is really hard..
Mobile sucks, I use RIF instead, or old.reddit.com if I am roaming internationally and want to read some text only subreddits.
> That's the thing though, with static sites where JQuery is used only on updates to your data, the initial rendering is fast. Browsers are really good at rendering static content, whereas predicting what JS is going to do is really hard..
Depends how static the content is. For a blog post? Sure, the content should be delivered statically and the comments loaded dynamically. Let's ignore how many implementations of that are absolutely horrible (disqus) and presume someone at least tries to do it correctly.
But we're all forgetting how slow server side rendering was. 10 years ago, before SPAs, sites took forever to load not because of slow connections (I had a 20mbps connection back in 1999, by 2010 I was up to maybe 40, not much has changed in the last 10 years) but because server side was slow.
If anything more content (ads, trackers..) is being delivered now in the same amount of time.
Reddit as a company obviously wants more users; a design that lets people scroll on through images ad nauseam is certainly better than a design that is more information dense, so if that's something you'd cite as an example of "better in certain use cases" then I agree, otherwise there's plenty of reasons to use old.reddit.com from an end user's perspective.
The concept of Eternal September applies.
It still sucked. It just sucked differently. I'll admit it was better for the user's battery life, but even the article shows that it was not any faster.
GMail, the first real "client-side" app, was so far beyond Hotmail / Yahoo Mail in usability that it's hard to even phantom ever going back.
You could switch to the horrendous non-Ajax interface.
I never realized that before, always thought Gmail was the first Ajax webapp.
The more modern style of heavier client-side js apps lets you use software development best practices to structure, reuse, and test your code in ways that are more readable and intuitive. You're still of course free to mangle it into confusing spaghetti code, but the basic structure often just feels like a better fit for the domain if you have even a moderate amount of interactivity on the page(s). As the team and codebase grows the structure starts to pay off even more in the extensibility it gives you.
There can be more overhead as a trade-off, but for the majority of users these pages can still be quite usable even if they are burning more cycles on the users' CPUs, so the trade-offs are often deemed to be worth it. But over time the overhead is also lessening as e.g. the default behavior of bundlers is getting smarter and tooling is improving generally. You can even write your app as js components and then server-side render it if needed, so there's no need to go back to rails or php even if a blazing fast time to render the page is a priority.