Modern JavaScript has made the web worse (2020)
chaseaucoin.com
chaseaucoin.com
Except that browsers no longer cache across origins anymore, so this doesn't work, also there are just a huge number of libraries and versions, so even if they did cache it, it's unlikely to result in much benefit.
https://htmx.org - an 11k library that pushes HTML forward as a hypermedia, making things like AJAX, SSE and CSS transitions available directly in HTML
https://hyperscript.org - a 20k library that replaces jquery/javascript with an inline, HyperTalk inspired syntax
Both can be included on a site without any build infrastructure, and are attempts at bringing the joy of hypermedia and the joy of scripting, respectively, back to the web.
SPA makes things complicated, server-render does not handle all user cases either, is there a middle ground: that I still can manipulate DOMs on the client side but not like SPA that goes all way in. That is, something likes jquery(the best/simplest API ever even after ES6), but with virtual-DOM. Not sure if Mithril etc fits the bill.
hyperscript is a client side scripting DSL that attempts to improve on javascript/jquery with an event-and-DOM-oriented syntax:
<input type="text" placeholder="Search..."
_="on keyup
if the event's key is 'Escape'
set my value to ''
trigger keyup
else
show <p/> in #quotes when its textContent
contains my value">Doing an analysis of the JS bundled with many major sites is an utter horror show: React is big and bloated, alternatives like Preact exist but no-one cares. React provides The Best Developer Experience so that is what we shall use. GraphQL is the cool thing to use these days so we’ll throw in a giant client library along with all our query text. Sure, browsers handle REST out of the box but that’s not what works best for our developers. We’ll use CSS in JS despite the performance being worse, it’s what our team likes. We’ll bundle a giant CoreJS shim to all browsers even though the vast majority won’t need it. Running two builds is too annoying to set up in our workflow. The site loads fine on my MacBook Pro so why stress what Lighthouse says?
So on and so forth. For years I’ve heard that this isn’t a problem because all the extra developer productivity means they can move so much faster. It’s been long enough now that I’m comfortable dismissing that argument as nonsense. And many users are essentially trapped: for example, I bank with Chase and their web site is absolutely atrocious. I talk to friends and they say the same. But the UX of online banking is very rarely a reason for anyone to change bank so the product folks aren’t going to push for performance. It’s something developers have to proactively care about and as an industry we just don’t.
I hope eventually we see the industry change but for now it really feels like no-one cares. We’re prioritising the speed of the shovelling while ignoring the quantity of shit.
I think this is a mix of good old cargo culting and how hot the dev market is. Small companies don't have the leverage to tell their engineers "no" when they do a bit of resume driven development.
React makes sense for many of sites at larger tech companies paying big salaries because many of them are delivering a richer "application" experience. Some engineers blindly follow what "better" (massive air quotes) companies are doing. Others who want to work at these companies want the skills that will make them more hireable and so choose React. Devs who are not in either of these other camps make a small enough group they don't generally get their way.
Plenty of things are basically websites with forms and a dash of interactivity. Building a full single page web app for this is a waste of everyone’s time and their customers CPU cycles, and it’s not even faster to develop most of the time…
My current job is a fully fledged web application for a B2B IoT platform, with soft real-time data and huge interactivity. React et al. fit this better, and because we have some control over who and what devices are using it, it’s (frankly, mitigated if you know what you’re doing) overhead isn’t a problem.
I love React, I really do. But it’s not the right fit for everything, and I’ve earned a huge amount of money coming in to save projects that are failing due to that incorrect choice.
The reason I was told was that they wanted the "components" framework to support modularity and reuse. Is there an alternative for that purpose?
May be something similar should be there for other frameworks too.
Vendoring every dependency and having to manually keep track of all the updates was objectively worse than NPM as well.
It looks and feels a lot more like "real" programming now but the whole house of cards seems to tip over and burst into flames every other week.
It doesn't actually empower anything - it acts as a scolding nanny prohibiting people from making things explode.
It does this by imposing a narrow opinion about things that's constantly changing with each release as it herds the programmer through very specific and alarmingly complicated ways of doing things.
It's fundamentally a tool of oppression, not one of expression and one of coercion and not liberation. I hate it so much.
Before react I hated UI programming so much. But the way react deals with state makes it so much easier to build and maintain complex applications.
All you have to do is define how your application responds to any given state and provide explicit controls for asking to update that state. If you do that correctly, your application will be predicable and easy to reason about.
The biggest challenge is it's just not the normal imperative programming model that most devs are used to. It takes time and understand to do correctly, but what doesn't?
I'll readily admit to being a passionate radical about this stuff. The things I have to say are basically just a bunch of bomb throws and I don't feel this is the appropriate place nor do I have the requisite time.
Rest assured, I've put in a considerable amount of time and effort into my thoughts on the matter and we'll likely disagree, but let's not do that here.
I'll think about how to best present it gently and prepare something.
The stuff I have is really much more for the STS people who think Silicon Valley should literally be dismantled brick by brick. That's a different audience than my fellow startup engineers (I've got my feet in many conflicting camps)
When someone has a strong negative take on something I thought was great, that's a perfect opportunity to learn deeply about trade-offs or concerns I might not be fully aware of.
If nothing else, it gives me an opportunity to evaluate potential issue, put guards in place to reduce the impact, and arms me to defend my choices should the need arise.
Real question; not being snippy...
I didn't think React had any state management included. A lot of people I've spoken to seem to use Redux, a third party library for handling state.
Is my understanding incorrect?
However, that _is_ limited in that you can only access state inside the current component, or pass it down the tree as props/context. If you need to access data broadly across the component tree, or the data itself does not lend itself to a tree-shaped usage pattern, or you need to minimize the number of components that re-render when you update, or you need to use it _outside_ the component tree, then you may want to look at an external state management library.
I've talked about the tradeoffs in these approaches numerous times:
https://blog.isquaredsoftware.com/2021/01/context-redux-diff...
https://changelog.com/posts/when-and-when-not-to-reach-for-r...
https://blog.isquaredsoftware.com/2020/05/blogged-answers-a-...
All that said: React makes writing an application with any meaningful amount of complexity _vastly_ easier to do than trying to do it with either preceding UI frameworks (AngularJS 1.x, Backbone, etc) or jQuery. It isn't perfect, but it's well-suited for a wide range of application development use cases.
Redux takes that to the next level but is based on similar principles of "reactive" programming. For complex state heavy applications it's extremely powerful, but often overkill for many smaller applications.
But I also think 'react' means two different things. One the one hand, it's "just a library". In industry, it tends to mean... react + JSX + react-router + redux + react-this + react-that + react-redux-this-and-that all tied together with create-react-app. Plus its own command line tools, and browser plugins. It starts to feel very much like a framework then, if not a platform of its own.
On another note, most of these complaints, IMO, aren't even specific to React. We were barreling down this future during the days of jQuery.
ReactJS has a wildly inflexible architecture that aggressively forces their users to conform to an orthodoxy. As an example let's say we have the following code
function C() {
var A = {
something: () => console.log("hi")
},
B = document.createElement('div');
B.onclick = () => A.something();
}
This small snippet of code violates "best practices" in react and thus is almost, but not quite impossible to do.See the problem here is that B and A are directly interacting with each other. If we were to map things in react-land, they would show that C has "children" of A and B and here A and B talk to each other "horizontally" which is heretic to the purity of the orthodoxy.
The hierarchical nature here is an unwavering assertion about the world. Essentially the claim is as follows:
C
/ \
A---B
The A <=> B is what forces us to wear a scarlet letter and live on the edge of the town.Therefore we no longer solve a problem. Instead, we are imposed upon us an aesthetic puritism do to a natural belief of "props down, events up". A popular way to do this basic programming technique that's been readily available in effectively every programming language since the first digital computer (Plankalkül had it in 1942) is the usual suspects either add "a new testament" to the orthodoxy, in this case with something called "redux" or figure out an acrobatic way to comply.
Let's do the second. So we need to "pass down" things that will "pass up". We have a solution, now we must go backwards, first we will go into "classes" to make things more orthodox.
class A {
componentDidMount() {
this.props.connector(this);
}
something() {
console.log('hi');
}
render() {
return;
}
};
class B {
render() {
return <div onClick={ this.props.onClick }>
}
};
class C {
constructor() {
super(props);
// here's our connecting function
this.connector = this.connector.bind(this);
this.onclick = this.onclick.bind(this);
this.state = {connector: ''};
}
connector(obj) {
this.setState({connector: obj});
}
onclick() {
this.state.connector.something();
}
render() {
return (
<A connector={ this.connector } />
<B onClick={ this.onclick } />
);
}
};
So to simplify this flow A -> B
We now do C -> A -> C -> B -> C -> A
Or as a diagram, we get the following: .---◢ ◣----.
.▶B---▶C--. \
| ◤--'|\ ▼ /
\____/ '►A-'
See how we do multiple round trips passing things through C in order to maintain the hierarchy? This is how we stay within the orthodoxyIf this looks like Ptolemaic astonomy, that's not a coincidence! In Ptolemaic astronomy the assumption of Earth being the center of the universe was enforced as the orthodoxy. As a result you got epicycles upon epicycles because the simpler model was forbidden.
People were so committed to the more convoluted orthodoxy that anyone who questioned it was put on trial for heresy.
Claiming that A -> B was even possible was the crime.
The great success of React is in enforcing a new kind of authoritarianism: it enforces doctrine by explicitly disallowing heretical code.
A problem that I have never seen before, an extremely complicated description, a terrible implementation in react using class components, some weird circular diagrams.
This looks like it's generated by GPT-3.
What is this piece of code even supposed to do?
function C() {
var A = {
something: () => console.log("hi")
},
B = document.createElement('div');
B.onclick = () => A.something();
}
In react: function C() {
const A = {
something: () => console.log("hi")
};
return <div onClick={A.something} />
}I'm glad you disagree btw. If everyone agreed with me than honestly, I'd not be pushing hard enough.
Horizontal message passing is really a state related issue and lives outside of React.
You can manage your state however you want and then wire up the components however you want. Since those two things are separate concerns. Although there are a ton of options in the ecosystem to do that.
"If reality falls outside the doctrine and really can't be denied then instead of fixing the assumption more often the orthodoxy is amended. A new wing in politics, a new testament in religion, a new movement in the arts, and a new version in software. It permits the avoidance of admitting the failures of orthodoxy while permitting a mechanism to address its shortcomings."
I don't think we'll come to an agreement on this and that's fine, it means I am staking a clear and controversial position which is my goal. Honest people can disagree and I really do appreciate your honesty. Thanks
Isn't it possible to connect your abstract ideas to a real world example? And why create en extremely obfuscated react class implementation of something that can be done in 3 lines of functional react code?
Let's say you have things with locations and a map (scooters, restaurants, hidden gold, whatever). You click a thing, it highlights it on the map. You click the map, it highlights a thing.
The obvious to me way of doing this is singletons (or globals).
You've got some routine itemhighlight(thing) or mapcenter(thing) and you generate the things on the page and use something simple like html data attributes to pass things around.
In react there's a fairly unorthodox hack I've got to do things like this but normally you'd have a map component and then some list component with item components.
Then when you tap the map, the stuff is passed up to a container component that gets passed to the list component that goes back to the item component, so long as you create some connections for that to happen.
Everything goes up and down the hierarchy. You don't just directly talk horizontally.
Now sure, there's arguments for and against both approaches and they are as contentious as type systems and editors. But the question was about the "scolding nanny".
Without react you can do both approaches, the first of which requires competency and skill to do well without creating a mess sure. But in react you are precluded from doing the first unless you wrangle it and work around the framework.
It disciplines and limits your freedom. I understand corporate hierarchies, pecking orders, and reasons for doing this. I'm a true anarchist though and that limitation really pushes my buttons.
Given all that, I use react regardless because I first and foremost try to be responsible adult and think it's the current most popular and professional way to do things for the day I'll eventually move on and hand over my code to someone else.
But I fucking hate it. It's a seething and very unhealthy vitriolic hate.
If you want to go for a sane way of managing global state you can use redux or context which don't require you passing state up and down the component hierarchy. But in my experience, usually when you design your hierarchy and your data well it makes most sense actually using the hierarchy to your advantage.
There's something fractal about it where the higher-level components deal with higher-level state and problems. In the case of the map you have a shared state between the map and the controls which should be explicit in my opinion and not hidden in one of the components' html data attributes.
The more complex applications I develop, the more appreciate the concept of having a "single source of truth" and not sprinkling states in child components.
So instead of the direct path, now you are doing a much more complicated circuitous path because the orthodoxy had to be amended.
Again, you're going to say this is good and I'm going to say it's bad. I see a problem where you see a solution. This is not reconcilable, that's why there's so many different programming languages. There's no right answer here and I'm ok with merely having a collection of opinions. It's like politics and religion. Whatever, people are different.
A shopping cart. The cart state exists in the header of the web page, but the "add to cart" button exists on the product description, far away from the cart. Ultimately, I think, it ends up being a question about state management which is always the hardest part of UI frameworks IMO
These days you can do it with a useState or useReducer hook but there are countless ways to implement it, react or not.
That said,
>The great success of React is in enforcing a new kind of authoritarianism: it enforces doctrine by explicitly disallowing heretical code.
I don't think this is a bad thing, after all the success of Rust is also predicated on explicitly disallowing heretical code that may have been commonplace in C. Constraints lead to more maintainable code, which is ultimately what frameworks these provide. I don't think your complaint is unique to React due to the fact it's HTML that influences that hierarchal design. That said, I'm not a front-end dev, and I my exposure to UI patterns is relatively limited; so I'm looking forward to your eventual book.
Button Press -> State -> Shopping Cart View
Just have the state have a function for dispatching a change to the shopping cart which is passed to the button component and pass the actual state to the shopping cart view.
You can have the state live in a parent component, use redux, use context or go more hacky.
My initial reading of OP's post is that this is the "hack" he doesn't like (even Context wasn't all that encouraged in React IIRC). My amusement, however, is this is, to him, a fundamentally philosophical disagreement with the design of React
const B = ({onClick}) => <div onClick={onClick} />;
function C() {
const A = {
something: () => console.log("hi")
};
return <B onClick={() => A.something()} />;
}That's the entire point. Software is eating the world, and there's not enough talented engineers. We can't just wish thousands more talented engineers into existence, so instead we have to come up with tools that will make people that only have 3 months of coding school under their belt and money as their only motivation reasonably productive.
If you're a god engineer, you have experience of working around constraints. That's just another one.
An excellent programmer will write excellent code using React, in Java or in C++. It's not about the tool, it's about the one wielding it.
HTML, CSS and Javascript are already extremely high level and capable. Do some xlib programming some day if you want that to be obvious.
So user clicks something -> app state gets changed -> modify DOM in response.
Here's a good description of a framework agnostic approach.
(i'll use this opportunity to plug my project, https://campfire.js.org)
The value of “guardrails” like type checking, borrow checking, and simple APIs is they allow you to turn your brain off when coding. I don’t write code because it’s an artistic expression of self, I write code because it’s a lowish stress job and I need to eat.
In my free time I get some joy out of writing clever code but by far 99% of the code I write I want to be boring.
All crafts have this - the corporate musician working on commercials and tv shows that's just trying to raise a family and "The Artist" that wants a free expression of their very soul.
I'm a slightly crazy person who is passionate about the liberatory potential of technology and how it reshapes society, hopefully as an empowering tool that benefits all. To quote Fred Brooks “The programmer, like the poet, works only slightly removed from pure thought-stuff. He builds his castles in the air, from air, creating by exertion of the imagination."
While you are happily working within the system, doing your job competently, and enjoying the fruits of your labor.
We can still be friends, but I'm going to be that wacky bird pushing the envelope, it's in my very soul and I don't think I can change that.
I think one thing that would help strengthen your stance would be a plausible explanation for why people seem to actually like React and friends so much.
Maybe your experience is different, but I'm often seeing people want to use React or Vue and lament the times they're stuck with JQuery or something more "old-school".
I recently transitioned from being a developer to being an accessibility engineer. I've been able to see first hand how the user experience has been neglected, especially for people with disabilities.
A lot of the JS frameworks are getting better at A11Y, but its still a major work in progress.
There is always a time vs end user experience tradeoff, even with physical goods. I think it's part of a bigger trend towards (more prolific) crappy stuff generally.
I do think there is space for tools that improve the user experience whilst not regressing on easy of development.
Agreed. I feel like I spend 50% of my time on here promoting Svelte which is wildly out of whack with how much I actually use it but to my mind it’s a great example of a tool that prioritises developer experience and user experience without compromise. There is hope.
If developers struggle with performant technologies / methods / frameworks, I'm sure they're going to end up producing crap apps in the end still.
Rather than complain, we should be focusing on making good performance the happy path. In fact, I'd say that's most of what the latest frameworks that are popular focus on, so I don't really understand the issue.
If you build the developer experience, they will come. If you don't, I hate to say it, but everyone has mouths to feed.
In practice I load every webpage once (even very complicated applications can be loaded in under 2MB), and then go on my merry way.
Web development leverages a terrible developer experience to create a terrible user experience.
Or that building large web applications in jquery or vanillajs can't lead to problematic code even when junior developers are used?
For example Next does a pretty good job of code splitting and offers rendering solutions from 100% client side to 100% static, as in no React runtime at all. Building a performant Next site that only pulls in the JS it needs is quite doable now.
React server side components seem at least interesting here. I still have no experience with them but they do at least claim to tackle some of these issues. As I understand it other frameworks like Svelte and Vue have been exploring these ideas too.
I think the bleakness will continue and there will be a long tail of it. But I really do think better websites are coming and in many cases are already here.
I feel the same about iOS apps -- they are all adventure games.
And in-place editing on a phone? Just fill the whole freaking screen with a big editor window in a giant font where I can target the cursor with my fingers, and let me submit it to the field when I'm done.
And get off my lawn! :)
How? Why? Efficiency?
My company does complex cloud and on-prem web-based apps, JS front and back.
These inefficient frameworks make our developers more productive and allow us to design, deliver, and fix fast. Storage is cheaper, bandwidth is cheaper, processing cycles are cheaper, all are cheaper than developer time.
And these powerful frameworks give us great speed in iterating new features, which makes our customers happy.
The article is too focused on efficient use of computing resources at the expense of ignoring developer costs and customer satisfaction.
Then you've certainly run into power users.
Chances are browsers can load and display a 2MB server-generated HTML table faster than the DI system in your 5 MB angular app can start all the required services to be ready to launch your pagination component.
However once it is ready it may be quickly apparent that users would be much more productive using that giant table and CTRL+F than a laggy angular app that would struggle even handling that much data at once in an idiomatic way.
Of course I am making this up to illustrate a point. However I use "one giant HTML table" as a sort of bar to meet when developing in modern frameworks. If with this insanely complicated and large array of tools I can't even do better than that (faster to implement!) competing solution, I might as well not bother.
That "a bunch of large server-rendered HTML tables" just so often happen to be the previous solution that was in place, and power users are likely to complain if we do worse, is just the cherry on top.
To do better we often have to avoid certain things that would be considered modern. Like not putting lots of empty space in our layout, no server-side search that would introduce too much (pointless) latency compared to client-side, and some un-idiomatic stuff to actually handle large[1] amounts of data without change-detection/updating in our framework of choice eating user's CPUs for breakfast.
[1]: The amount of data/elements at which change detection in idiomatic Rust and Angular becomes slow wouldn't have been considered 'large' 15 years ago. Though obviously people then had to put thought into this stuff and it certainly wasn't automatic.
Related anecdote: I just did a production build of the Angular 13 app I'm working on and it was 686K. That includes all the Angular framework, and a component library which includes a data table.
Your build is half the size of twitch.tv's vendor.js.
If you go on their front page, then click a stream, your browser will have loaded around 15MB of JS (~3.4MB over the wire).
To be fair they're a video streaming service so they probably don't care about a few extra megabytes here and there, but on lower spec'd hardware you'll feel all that JS: a solid 5s of CPU time just spent executing JavaScript on my thinkpad during that test, not including the time to load it.
And it's not like they're done. If you then do pretty much anything, it'll have to load even more. Apparently if you click a name in chat, it has to load another 998.96KB JS file (features.chat.components.viewer-card-*.js) to render those tiny cards that contain maybe 50 bytes of information. That's a good bit larger than your entire application!
There's operating systems that fit in less than what twitch needs to show a glorified tooltip. On my hardware they could probably boot in that time too.
Our apps are related to compliance and risk management with a good sprinkling of custom developed workflow. Most of the screens users see are fairly light. It isn’t the amount of data that matters to our users, it’s what we do with it.
And how quickly we can new things when they realize they need new.
For me this is a leap. I can't think of many examples of software which I use where new features have actually made me happy. Normally it's just change which forces me to learn something new while I'm in the middle of trying to accomplish something actually productive.
I think our industry over-estimates the value of "new features". But in my experience 90% of new features provide neutral or negative value. If—instead of a new feature—the software I used released a performance improvement, then that would actually help make me more productive.
They care about the features in our products and the frameworks we use allow us to do cool fast.
I can remember back in the day at Travelocity they couldn't hire JavaScript developers to save their business. A $100 million business and the darling of the travel industry could not hire competent front end developers at all. Its how I became a developer, involuntary reassignment from designer.
I can also remember Travelocity trying to solve this problem with GWT (Google Web Toolkit). This mistake of an application compiled Java to JavaScript for people who probably should not have been writing either. Its all good so long as the code never needs changes or updates at which point Java developers wanted JavaScript developers to fix their obfuscated code.
How hard could writing this rinky dink language possibly be? Back in those days there were some actual challenges, but they were an inch deep and a mile wide. There were many technical areas to own, but only two separated the grossly incompetent from the barely employable:
* Cross browser compatibility (IE made this more challenging).
* The DOM. Then, just as now, tree models broke the souls of many software developers. I have never figured this out, because elementary schools are able to explain abstract concepts as tree models to children, but many adults cannot and will never understand the idea on even the most primitive level.
jQuery came and saved the day. No more walking tree models. Everything is now a chained method or a CSS selector through a very slow Sizzle engine. Now everybody and their dog could add events and text to a web page so long as they could read the jQuery API.
In hindsight none of this is surprising in the least. The surprising part is the compensation. Back in the day when the work was hard front-end developers were paid next to nothing. You were much better off being a Java developer where you could barely have a pulse and earn 2-3x as much. As the problems got easier and the number of available candidates blossomed the compensation surprisingly went up... slowly.
A URL that is now less Universal than ever, pointing to an application more than a piece of content
Content that is not self contained in a single document so it is hard to archive for the future
Content that is not served with the page nor containing a universal reference so it is hard to scrape and catalog
A profound inability to inspect websites because they are now transpiled via frameworks and emit something obtuse and only machine, not human readable
Content that is now in a non-generalized method of access so instrumenting it to fit it for different purposes (the "Free" part of "information is meant to be free") is now fragile and dubious
And more controversial:
The careful separation of concerns of the Javascript (Controller), HTML (Model), and CSS (View) gets tossed together and entangled in a single stream of hybrid languages where they no longer are separated. Instead people rely on less rigorously made tools to achieve the same ends with increased difficulty, less reliability, and less functionality - all cost and no benefit.
Links to individual pages would be useless to archive because they're not documents. Kinda like "Why would you bookmark a individual app window?"
You can scrape us with a browser, but why would you?
You can right click inspect or use react devtools, which is nice if you're trying to understand things. That part is way more accessible than an equivalent iOS, Android, or Desktop app would be.
Oh and we don't need to build an iOS, Android, and Desktop app! It's a single webapp that works in any client of your choosing.
Plus you get fresh updates and bugfixes with every page load, no delayed update cycle. This may be controversial if you dislike a UX change we make.
IMO, the setting where open source communities are likely to grow is the right place to share code. This is also the setting where code is most likely to be understood, as understanding a codebase is very hard. Sharing code is not just a matter of dumping original source code to the public, and I think the use case around ordinary users examining source code is very, very niche.
And how should compiled-language communities like Rust handle the issue of sharing code? Should they distribute the original source code with the expectation that their users shall compile on their end? Is that the right way to share code, or is that just dumping code to the public?
Yes, there's holes in that argument (you don't get to inspect the server side code for instance), but it's a statement from principle. The web was intended to be an open platform in that "I'm free to inspect and repurpose within reason" kind of way.
The radical philosophy and promise of the web and open source has been sublimated and replaced with a cynical variation, a form of elite pirate capitalism.
If "we shape our buildings and afterwards our buildings shape us." and we want to go back to the virtues of the open society and dismantle the panopticon of personal data the web has become, then this is the wrong way to construct the cyber-buildings of tomorrow.
I built https://mkws.sh as a solution to at least static site generation. It can be enhanced with a Makefile but for now it's simple enough. I don't believe static site generation is a JavaScript job, and to be honest, I don't believe JavaScript belongs on the server side.
1) Client-side-rendered apps that haven't embraced hydration of pre-rendered HTML suffer for it. Not because the JS is necessarily too large, but because it blocks the content from being visible. This would be bad even with a small bundle. Luckily this is an easy problem to solve today, but not every site has done so.
2) Many public-facing sites are afflicted with marketing scripts. I've seen sites with (I kid you not) several times the amount of marketing JS (by weight) as they have actual functionality-giving JS. The actual devs often don't even have control over these scripts (thanks to Google Tag Manager), and even if they do they probably don't have a say in what can be removed.
3) Complex sites/web-based tools are a separate beast. You're not optimizing for first-visit, you're optimizing for responsive interactions. This has even less to do with bundle size, and often not even much to do with JS itself. In my experience the limiting factor on these sites is usually reflow (DOM/style changes).
- JS development has a low barrier to entry, so there is a wide/diverse range of developer skills and knowledge
- Most (webpack) tutorials don't cover build optimization, like tree-shaking, especially entry level, which is normally what people find to "just get the job done."
- There are too many options for frameworks for people to make _good_ decisions, so they often fallback to _popular_ decisions
This isn't even a recent problem. I have a few clients that wanted to use old-school template packages, like metronic, and that is a massive bloated build, and yet it's basically jquery+bootstrap with a handful of libraries.
The biggest thing is, as professional web developers, we have a responsibility to the end user to make a web page load fast and be usable quickly, and I think we often over-look that. I don't care if your framework is a no-build thing, or uses webpack/rollup/etc., the real thing is if a user doesn't have to download 50MB of javascript for a single page, especially if the end result of that page is considerably less than 50MB worth of text, styles, and images.
The flip side is, most clients just want their project done quickly so they can make money. There's nothing wrong with that, but it can't be at the expense of their users, and developers should be able to give good consultation and advice to their clients about the trade-offs of libraries/frameworks/build tools/etc. and the impact they will have on the end-users.
Personally, I like building without extra build tools. `script type="module"` is great, and smaller frameworks (my go-to is hyperapp, but there are several others) are often not awful to grab a local es6 copy and toss it in your public web directory, import it, and go to town.
I think this is a very subjective take. There is also a strong argument that the web is much better today because of modern frameworks and technologies. The web has shifted from being a place for basic content and documents to a full-blown application platform. 10-15 years ago, if a certain application was only built for (say) macOS, well, tough luck! You won’t be able to use it. Today, many popular applications can be used in the browser on any device and any operating system. (Examples like full office suites including MS office and Google docs, or photo editing apps, or music streaming platforms, or video conferencing.) That’s a pretty incredible advantage and improvement to the general state of software, and it’s a very strong improvement for users who no longer need to worry about incompatible software or installation processes.
I would argue that this advancement would not have happened without frameworks. Or at the very least, it brought about frameworks. Since the web platform itself is not designed for applications, any large application will probably end up writing some sort of abstraction on DOM rendering and state management, just to make it halfway maintainable. So if we want web applications, which are very beneficial in many circumstances, frameworks and tooling are a part of that.
Of course bundle size is still a problem to worry about. It’s a problem inherent to the benefit of the platform. Typical software can make the bundle as big as they want, and you download and install it once. The web platform forces you to care about the size in a way that just isn’t necessary for other platforms.
“Modern JS” is really not what is making the web worse. What’s making the web worse is ads, tracking, platform-lock-in, big monopolies, censorship, spam, poor content safety practices, etc.
Like, of course you don’t need a big framework for your blog or basic content site. It’s all about choosing the tool for the job. Half the time, the blogger probably just wanted to play around with a new technology. It really doesn’t matter that much for small little projects that are just people playing around.
Bundle size is important when you have a big enough user base and really have a need to optimize for poor internet connection and slower devices — but it’s just bundle size. You’d get even bigger bundle sizes without using modern tools like webpack. The bundle size comes from the larger types of apps we’re building now that we didn’t used to build, not from web frameworks specifically. IMO, that makes bundle sizes an important, but relatively small aspect of “problems related to the web.”
There's an easy solution though. Just don't use javascript to make your personal websites. The corporate web can wallow in it's own filth and decay for all I care. If the humans on the web make websites without JS the web can be, and is, still great.
* JS's history is all about "quick and dirty". jQuery in older times was meant to paper over the quick and dirty and give developers more convenience, and old JS without JQuery was pretty awful
* we are asking JS to do things it was never meant to do; in particular, the desire for "app-like" experiences and SPAs.
* JS is very backward compatible, which means old webpages can be archived, but also means that all the warts are still around.
* JS interpretation depends on browsers, which means if you want to use some modern features you will have to use some kind of transpiling, polyfill, and or framework to get some consistent behavior on all of them (jQuery in older times, babel today), and the differences in browsers means that these adapters have to be mind-bogglingly complex a lot of times
Frameworks being large and taking a long time to parse isn't the fault of JavaScript or NPM.
The 2021 web is a Boeing 737 Max.
It's also hard to picture a news website where the webpack chunks are going to be a noticeable fraction of the total page load expense, when images are factored in.
For example, on CNN's homepage, of the 10MB of data and 200 requests my browser did, around 1MB of it was actual core JS served from a CNN domain, and even less of it looked to have ever gone near a package manager.
1. parsed
2. lexed
3. eval'ed and executed
Not cheaply, but expensively.
What you're talking about is another problem