
The JavaScript Black Hole: A playbook for ethical engineering on the web - orthecreedence
https://www.obsessivefacts.com/blog/2020-04-04-the-javascript-black-hole.html
======
guessmyname
I had the opportunity to work in the analytics team at MindGeek a couple of
years ago. My team would spend days researching about all these seemingly
useless features in modern web browsers to find new and better ways to track
users across all our websites. I still remember when the HTML Canvas Element
[1] was introduced by Apple almost two decades ago, many of these adult
websites managed to increase the accuracy of their corresponding device
fingerprint algorithms [2] by leveraging the power of the new APIs. In fact,
one of the reasons why Fabian Thylmann tried to acquire XVideos back in 2012
[3] was because their analytics team had engineered new ways to track users
using WebGL [4] which was still quite new. I don’t know if device tracking is
still relevant for their revenue model, but I am sure they still have the code
running in most _—if not all—_ their websites for one reason or another.

[1]
[https://en.wikipedia.org/wiki/Canvas_fingerprinting](https://en.wikipedia.org/wiki/Canvas_fingerprinting)

[2]
[https://en.wikipedia.org/wiki/Device_fingerprint](https://en.wikipedia.org/wiki/Device_fingerprint)

[3]
[https://en.wikipedia.org/wiki/XVideos#History](https://en.wikipedia.org/wiki/XVideos#History)

[4] [https://en.wikipedia.org/wiki/WebGL](https://en.wikipedia.org/wiki/WebGL)

------
hn_throwaway_99
> JavaScript is a toy programming language.

Bullshit. Yes, javascript has evolved a ton over the decades, and it has a lot
of cruft that it pulls with it. So what? So does virtually every other
successful language.

I was a Java developer for over 15 years before I switched to mainly
developing in Node/Typescript, and I feel I am _much_ more productive in this
ecosystem than I was in Java.

~~~
Spivak
I think the problem is ultimately a combination of popularity and forced-usage
that creates opinions like these. JS has remarkably less weirdness and cruft
than other ubiquitous languages like Bash and Python because of how quickly
browser vendors are able to iterate on it. Every little piece of the language
has millions of eyeballs on it.

~~~
int_19h
The vendors are able to iterate when adding new features, but they have to
maintain all the old stuff for back-compat reasons. And some of it is core
language behavior that cannot be changed but which does surface everywhere -
e.g. equality and implicit conversions.

When you account for that, I would strongly disagree that JS has less
weirdness and cruft than Python.

~~~
ttty
I never had a single == in my codebase. All are ===

------
duxup
This reads like sort of a grand collection of mostly legitimate individual
technical complaints about a lot of things JavaScript / Browser.

But I still can't get past the fact that when I work for a company that wants
to write a web app it is just like magic that it works across all these
operating systems, phones, and etc provided they have a capable browser.

To me that utility is amazing. I don't see how to get around that, and for all
the issues listed, I don't see a reason to throw the baby out with the
bathwater / not really sure what the alternative is supposed to be.

As for privacy, if we weren't doing things in a browser as much and you had to
install an app... would OSes be a better host / not have all these issues?

~~~
timw4mail
I don't understand why there's so much avoidance of server-side rendering.

~~~
hombre_fatal
Well, you can at least appreciate the simplicity of a server just being a
simple API that all of your clients use in the same way rather than the server
having an API and then also generating the page for one specific idiosyncratic
client that has this weird feature where you can serve layout to it.

Also, once you have any interactivity, there's a point where it's nicer when
all of the application is in the domain of Javascript instead of only parts of
it.

Server-side rendering has some nice upsides, but there are various trade-offs,
good and bad, at play here.

~~~
pdimitar
> _Well, you can at least appreciate the simplicity of a server just being a
> simple API that all of your clients use in the same way rather than the
> server having an API and then also generating the page for one specific
> idiosyncratic client that has this weird feature where you can serve layout
> to it._

Maybe I am misreading you because this sounds to me like "we only want to hire
JS devs".

------
headcanon
The issue with many of these major problems are (especially regarding 3rd
party scripts):

1) They are easy to add

2) Economic incentives are not aligned with technical rigor and security.

3) No matter how much we write and post on this forum, we're shouting into a
void composed of the 80% of developers who do not care, and the 100% of people
who pay them who do not care. Why should they care about the occasional user
getting compromised by russian hackers? "Not my problem" attitude won't get
fixed by social enforcement.

4) Progressive web apps + modern stack need an expert hand, and are not
straightforward to set up in most cases. Much more difficult at any rate than
setting up a quick react app. Next.js and others do well at making this less
difficult, but see #3.

Everywhere I've worked that just shipped a "static" SPA, doing so did not
materially affect the business over shipping progressive functionality.
Embracing "rigor" was seen by a waste of time to anyone who had a hand in task
scheduling, and why should they care? No PM or startup CEO is going to care a
whit about anything this article talks about, unless it happens to be central
to their business.

------
jtdev
Love this quote:

"Imagine an operating system where all software development must be done in
QBasic; it's an operating system that downloads, installs and executes any
program the moment it is encountered, without your permission, and it leaks
information about your activities to anyone who wants to spy on you. No it's
not Windows 10; you've basically imagined a modern web browser."

------
axguscbklp
>JavaScript frameworks such as React and Angular have transformed the web,
bringing us fully-fledged client side applications with functionality that
could only be imagined just a decade ago.

It's not like one couldn't create a fully-fledged client side application
before Angular and React.

------
_bxg1
> Gmail used to be fast, and now it's slow and bloated. On my fiber
> connection, it takes nearly two seconds to render anything beyond a loading
> animation (generally a bad sign) and several more seconds to fully stream in
> content for various sections of the page. Why so slow? A quick trip to the
> Network tab in the browser console reveals that more than 4.6 megabytes of
> JavaScript are needed just for the list of emails to first render. After
> that point, 8 more megabytes of JavaScript stream in and various elements on
> the page render asynchronously. All this while, a further 3.5 megabytes of
> XHR data are transferred across more than 60 separate API calls.

What this reads as, to me, is "Gmail, a highly-stateful tool, is downloaded
locally and then it requests a large portion of the user's inbox and other
data for usage."

I highly doubt the JavaScript is re-downloaded every time the author visits
Gmail. If it is, something has gone wrong. I don't think the initial load time
is a good metric of performance for a true web app; on subsequent visits that
12.6MB should be loaded directly from disk, just like the binary of an
installed native program.

Also, JSON is _leaner_ than HTML, so the only reason that "3.5 megabytes of
XHR data" would be larger than what was already being downloaded before is if
Gmail is loading data more eagerly (loading the first several hundred entire
messages of your inbox, for example, instead of just the subject lines of the
first 50). This eager loading would presumably be done to make subsequent
actions faster, and while we can debate the decision that was made in this
particular case about exactly how eager to be, that isn't exactly an endemic
issue like the author makes it out to be.

~~~
cousin_it
> _I highly doubt the JavaScript is re-downloaded every time the author visits
> Gmail. If it is, something has gone wrong. I don 't think the initial load
> time is a good metric of performance for a true web app; on subsequent
> visits that 12.6MB should be loaded directly from disk, just like the binary
> of an installed native program._

I don't know about Gmail, but this argument misses something important. A web
app with several megs of JS is most likely being developed and pushed to
production on a schedule (daily, or weekly, or something). So you're probably
re-downloading the whole thing every few days.

> _Also, JSON is leaner than HTML_

Mmmaybe. With gzip, the difference isn't that large. And since not all
developers are perfectly careful, the initial JSON will often contain stuff
that isn't necessary for the initial UI state, so server side rendered HTML
will often be leaner and faster.

~~~
_bxg1
> A web app with several megs of JS is most likely being developed and pushed
> to production on a schedule (daily, or weekly, or something). So you're
> probably re-downloading the whole thing every few days.

That's a fair point that I hadn't considered. But still: native apps get
updates too. I've been annoyed by really frequent update prompts. Maybe the
web streamlines the process to a point where devs may not notice the overhead
it's causing for users, but that still comes back to being a UX issue, not a
technical one, IMO. Maybe continuous-integration isn't a good idea when it
comes to client software in general. Maybe releases need to be artificially
slowed to a weekly or monthly cadence, for the sake of the user experience.

~~~
cousin_it
The problem is that the teams developing new features (or fixing bugs) will
all push for faster releases. So anyone who advocates for slower releases
needs to have a lot of political pull, for no clear political win. So it
basically doesn't happen.

------
recursive
As someone who has spent a significant amount of time with both QBasic and
javascript, the comparison between the two languages is off the mark.

QBasic has no built-in array sort. QBasic has no function references, and by
extension no anonymous functions. QBasic has no objects. It does have structs,
of a kind, but they're much more limited, and don't have prototypes or
participate in inheritance.

------
elldoubleyew
Genuine question as a rookie developer:

I write a lot of internal tools for my company used in
manufacturing/fulfillment. We generally deploy these as fleets of Raspberry
Pis. The front ends for these systems are generally pretty simple, they just
walk an operator through what they should be scanning, and for hardware
interaction I use a small node server. I serve a React App to these stations
(from an internal server) to render this UI.

What (modern) alternatives are there for this that do not use web
technologies? I've recently grown an affinity for ruby and attempted to
rewrite my frontend in Shoes, but the barebones documentation and lack of SO
answers made that a huge pain in the ass, not to mention the added steps in
deployment of updates. Going any other route just seems like so much more work
for no true benefit.

~~~
orthecreedence
Honestly, if what you're doing works, go for it. Using javascript/html as an
internal tool for UI building seems like a fairly decent use-case. You could
write your UI in some sort of native toolkit like QT/Gtk/etc but then you're
pumping dev cycles into making something that already exists and works
fine...for what? If everyone who uses your UIs already has a browser, then
you've hit a sweet spot: your client software is already pre-installed on all
the machines you need it to be, and the rest is serving HTML/javascript.

The alternatives for you are probably pretty time-intensive for you and
probably annoying for your users ("hey, install this program/app/etc"). I'd
say if you want to rely less on JS and use more server-generated HTML, PHP
might be the simplest option for you. People around here shit on PHP, but PHP
was "serverless" before it was cool and has a lot of tools to do exactly what
you're doing. But again, ask yourself what you gain by switching to another
technology.

~~~
pdimitar
PHP is definitely an awful recommendation for a RPi 4 though.

There are lighter weighted options that optimise for minimum latency and
minimum CPU overhead.

~~~
orthecreedence
If it's an rpi serving 400 req/s, yeah you're probably right. If we're talking
more about maintenance by a handful of people and a few hundred internal
users, PHP is fine and an rpi can handle that load just fine.

What minimal alternatives would you suggest given the constraints?

~~~
pdimitar
As mentioned in a sibling comment of mine, there are some alternatives:

\- Elixir's Nerves: [https://nerves-project.org](https://nerves-project.org)
\- Golang: \+ [https://github.com/tinygo-
org/tinygo](https://github.com/tinygo-org/tinygo) \+
[https://gobot.io/](https://gobot.io/) \+
[https://github.com/golang/go/wiki/GoArm](https://github.com/golang/go/wiki/GoArm)
\- Rust I suppose you can just directly compile for any SoC like the RPi.

------
chrischen
For the section about how javascript can only be added onto (such as with
typescript), I disagree.

Now that we have compilers and transpilers like Babel and Typescript, it means
we can effectively code how we want (even with different languages like
reasonml, ocaml, purescript, or ESNext), and in theory browser venders can
simply make a new target language or version of JS that these compilers can
target.

~~~
WorldMaker
A lot more of the ES2015+ features are supported by browsers today than people
seem to think as well. A large number of people still think of things like
arrow functions, let/const, async/await, and so forth as "esnext" features
when in many cases they are "estoday". (Assuming of course you don't need to
support IE11, and good luck if you do.) While TC39 has been trying to be very
strict about backwards compatibility, there's still a ton of room for language
evolution and it's been moving at a rather aggressive pace.

Also, it's hard to call any language like (Q)BASIC or Javascript a "toy
language" when it is used to build so many real world practical applications.
The esoteric programming language is full of some truly interesting toy
languages. Both Javascript and almost every flavor of BASIC has powered real
world applications for decades. The underlying fundamentals/foundation of JS
is sound enough that many things have been accomplished with the language,
even if it isn't aesthetically pleasing to some (or sometimes betrays its very
rough, "quick and dirty" development origins).

(Then there's of course the digression in whether or not WASM is also building
a sound VM option for languages that really don't want to work with JS
directly on the web/in web browsers.)

~~~
pdimitar
> _Also, it 's hard to call any language like (Q)BASIC or Javascript a "toy
> language" when it is used to build so many real world practical
> applications._

Can we stop conflating "it's popular because we had no choice but to build web
apps with it for two decades" and "it's a good language", please?

Mud bricks also saw huge usage thousands of years ago. Still doesn't mean they
were a good building material for houses.

~~~
WorldMaker
I don't conflate those things at all. I think it is a good language under the
hood, and it remains in browsers because it is popular. Browsers got rid of
VBScript for several reasons, and they'd ditch Javascript if there was a
populist uprising. (That seems unlikely and Google's efforts with Dart seem
pretty clear that there is little interest in a second language in the
browser, though we can argue that Google might not be capable of making a
better language than Javascript.)

Javascript is an interesting language on the evolutionary chart with genes
from Scheme and from Self. While those genetic traits are sometimes obscured
by the last minute bolting of an ALGOL-like syntax on top (by way of Java, and
thus the odd name), they are still fundamentally there. There are some really
smart (albeit quick) decisions underpinning the language that have helped it
to survive multiple decades of (ab)use on the web and elsewhere. It has had
its flaws, its evolutionary dead ends, its quirks, but show me any language
without those (and I'll sell you a bridge).

If there is a risk of a conflation problem here, I'd suggest it has more to do
with people conflating "easy/accessible" and/or "populist" with weak or bad.
BASIC is "bad" because it was made to be easy and welcoming to beginners. (But
it still got a lot of serious work done in almost every field, by just as many
[domain] experts as language beginners.) JS is "weak" because it was made for
being embedded in browsers. (But the web browser became one of the most
important forces on the internet for better and worse, and most of its
weaknesses have been scrupulously filed off in daily usage and security audits
and the pendulum swings between market competition and monopoly.)

~~~
pdimitar
> _If there is a risk of a conflation problem here, I 'd suggest it has more
> to do with people conflating "easy/accessible" and/or "populist" with weak
> or bad._

I never said that and never will because it would be quite naive. Let's not
resort to strawman.

I don't mind languages being "easy/accessible" \-- if I did I wouldn't make
Elixir my main language. There are many, valid, well-documented, warts of JS,
so much so that an actual book called "Javascript: The Good Parts" had to be
written. (I find that quite amusing.)

> _I think it is a good language under the hood, and it remains in browsers
> because it is popular._

You might be mistaking what you said with "we literally had no choice for 20
years except use JS on the browser" (VB, ActiveX, Java Applets et. al. had
game-breaking problems, cross-OS compatibility included, so they fell to the
sides). "Popular" is the consequence of having no choice for a long time, not
a function of any perceived high quality of JS.

Google's efforts with Dart failed simply because Google has a short attention
span and their numerous cancelled products can attest to that much better than
any argument I could make.

There's absolutely nothing preventing any corporation adopting any language
and slapping a small DOM access library on top of it. This is not being done
for HR reasons: the companies want to choose from a singular pool of devs so
its operations are easier and quicker. A valid business decision which has
zero correlation to JS being good.

JS survived because it was "the least bad" _at the time when everyone needed a
browser language_. Everyone is too busy making a living so we just rolled with
whatever the browser vendors and corporations half-begrudgingly (and rather
urgently) settled at. Assuming you hated JS, can you tell me with a straight
face that you'll sacrifice all your free evenings and weekends to produce
another browser language? For like 2 years?

> _It has had its flaws, its evolutionary dead ends, its quirks, but show me
> any language without those (and I 'll sell you a bridge)._

It will have them for a looooong time still though. Even if many will stop
supporting IE11 soon-ish, there's still a ton of baggage left that will never
get fixed.

The much more likely scenario is people will just start compiling language X
to WASM and will go with that when hiring frontenders. And we will see the
return of the full-stack role when you actually can work on the entire stack
only with Rust, D, Nim, C++, or your language of choice. It is very probable
we'll again start seeing web shops proudly touting themselves as "we only do
C++ (or PHP, or Pascal) here".

------
wincy
Thanks for posting, I’m interested in reading it. However, I’m reading the
article on my iPhone and the scrolling hijack is really annoying. It scrolls
less well than native scrolling and is jerky and makes it difficult to read.
Why do people do this with their blogs?

~~~
henriquez
Author here - there's no scrolling hijack on my pages. I also dislike this
sort of thing. Which iOS are you using?

~~~
wincy
iOS 12.4. When I scroll up or down normally the intensity of the flick causes
it to scroll faster or slower. It feels like there’s a “hard stop” on the
page, the scrolling stops sooner. Scrolling slowly seems to be off by a pixel
or something, almost like a judder. I didn’t see the same issue on Chrome on
my Mac.

~~~
adrianhel
Scrolling on iOS browsers is an utter pain due to rubber band scrolling. It
can be solved with -webkit-overflow-scrolling and hard work.

------
quickthrower2
As for the webrtc IP adress - check your one out here:
[http://net.ipcalf.com/](http://net.ipcalf.com/)

This works on one computer for me, and get obfuscated on another (on a
different network). Interesting!

------
okareaman
Excellent article, but I think it misses the point that most people are aware
that they are getting free sites and tools like gmail, reddit, twitter,
facebook for the price of being tracked an advertised to. What's the
alternative? Paying for everything?

Just install an ad blocker, turn off JavaScript or if you are really paranoid,
pick one of the many linux distributions to load up into VirtualBox and browse
the web that way, changing your distro daily. Use various VPN services on top
of it. Use Tor. Most people don't care enough to do anything like this.

~~~
notechback
I doubt that most people understand that using Gmail (or similar) means their
emails are analysed, much less that they are tracked across the web and that
such info is assembled by hundreds of companies and sold and resold many
times.

Most people in San Francisco might understand it. Do most people in Chennai,
Nairobi, Rio or even in Smalltown, USA understand that?

~~~
okareaman
I think you underestimate people

~~~
Shared404
As much as I would like to think that, I have to disagree. I've spoken to many
somewhat technically savvy people who when informed $product sells your
information, are shocked.

------
AzzieElbab
They should have given Brandon Eich a couple more weeks...

------
mwcampbell
Chrome OS is hardly a failure as the author claims. I have a non-techie friend
who uses it, and I hear that it is popular in schools.

------
cutler
Doesn't web assembly solve this problem? The author doesn't even mention it.

~~~
henriquez
Solves the issue of JavaScript being a toy language but not the issue of
treating the browser as an OS and forcing the user to execute unknown app code
in order to use the web.

------
tiborsaas
Stopped reading it at "JavaScript is a toy programming language."

While the author is not alone with this view, it's shared by many of my
backend colleges. With such a condescending view I will hardly gain any
insight I'm afraid.

~~~
axguscbklp
Yeah, JavaScript has problems but come on, just the fact that it has closures
and first-class functions (and did a lot to popularize both, for that matter)
makes it pretty cool in my book. It's a fun and powerful language.

The author also trots out the standard go-to argument of JavaScript haters. He
writes that JavaScript "has deeply ingrained quirks and bugs which can never
be fixed without breaking the millions of scripts that have made peace with
the existence of those bugs and depend upon the well-known workaround" and he
links to
[https://github.com/denysdovhan/wtfjs](https://github.com/denysdovhan/wtfjs),
a typical list of JavaScript's well-known type-casting quirks, etc.

Pretty much all languages have little quirks. Actual JavaScript programmers
usually learn how to avoid JavaScript's quirks pretty quickly and easily. In
my experience, people who fixate on JavaScript's quirks generally do not
understand the language very well. If they did, they could criticize more
substantial things about JavaScript than just things like "[] == ![]; // ->
true".

~~~
int_19h
What modern language doesn't have first-class functions and closures?

(Except for C, but in that case it's obviously by design, and for good
reasons.)

~~~
tiborsaas
Java only added first class functions relatively recently

~~~
int_19h
Java added them in version 8, which was 6 years ago. And it was one of the
last mainstream languages to add that feature - even PHP and C++ had it for
many years by then. So I don't think it's a useful metric for "cool" in 2020,
and it hasn't been for a long time.

------
Turing_Machine
I've never been impressed by the argument that JavaScript is somehow less
secure than native apps (which are still mostly written in C, and which have
full access to the hardware by default).

The mere fact that JavaScript doesn't have unchecked array bounds eliminates
about 70% of the really serious security hacks of the last 30 years.

~~~
jakelazaroff
On the other hand, JavaScript is executed automatically; your native app needs
to be downloaded and run manually.

~~~
hombre_fatal
But you have a lot of control over the web browser. You can run zero
Javascript. You can write extensions. You can easily see network traffic and
conditionally block it. You can block Google Analytics.

With native apps, you have very little control. You basically either run it or
you don't. You can't just pick the parts you want to run. And you need to use
a mitm proxy just to see what it's doing. The OS gives you no power here
unlike the browser. A native app can send a request to Google Analytics on
every keystroke and it's nontrivial to find that out compared to opening a
browser's network tab.

Native apps have some advantages like performance, but they are no free lunch,
especially when it comes to privacy.

