These days I see people casually adding network hops to web applications like it's nothing. These actually take multiple milliseconds in common scenarios such as cloud hosting on a PaaS. (I measured. Have you?)
At that point it's not even relevant how fast your CPUs are, you're blowing your "time budget" in just a handful of remote function calls.
If you stop and think about it, the "modern" default protocol stack for a simple function consists of:
- Creating an object graph scattered randomly on the heap
- Serialising it with dynamic reflection
...to a *text* format!
...written into a dynamically resizing buffer
- Gzip compressing it to another resizing buffer
- Encrypting it to stop the spies in the data centre
- Buffering
- Kernel transition
- Buffering again in the NIC
- Router(s)
- Firewall(s)
- Load balancer
and then the reverse of the above for the data to be received!then the forward -- and -- backwards stack -- again -- for the response
If this isn't insanity, I don't know what is...
What you are doing is like a machinist complaining about a carpenter not measuring everything in thousands of an inch or micrometers. The reality is that wood is soft and can shrink or grow. It's maybe not the best material but it's good enough for the job and it's cheap enough that you can actually afford it.
With web content it’s the exact opposite. Every time you are a bit lazy, and add another mushy, poorly optimized dependency, the cost is paid by every one of your users.
The better analogy is that the web is like an assembly line that serves content. Do you want wooden equipment with poor tolerances making up that assembly line which takes twice as long and occasionally dumps parts on the ground, or do you want a well-optimized system working at peak efficiency?
History and inertia also are nearly synonymous with "easier to use" in this context.
Plain HTML renders several order of magnitudes faster than post-load JS rendering, and yes, it is noticeable, especially if you account for variable connection speeds.
Most web devs develop on localhost and test on some of the best connections you can get today, leaving network performance testing as an afterthought at best... and it shows.
Well, "several orders of magnitude" is a bit much, but the point stands.
However, that's only during the initial load. After that, JS can just keep modifying the DOM based on the data retrieved from API, and never download HTML and construct new DOM again. If done properly (and that's a big if!), and where appropriate, this can be much faster.
> Most web devs develop on localhost and test on some of the best connections you can get today, leaving network performance testing as an afterthought at best... and it shows.
Very true! And on beefeir CPUs/GPUs, more RAM, faster storage etc.
For the last couple of years, I've been careful to develop on "midrange" hardware, exactly so I can spot performance problems earlier.
Primary and by far most frequent use case.
> After that, JS can just keep modifying the DOM based on the data retrieved from API, and never download HTML and construct new DOM again.
And then you can never return to the same page again, it's gone into the either, and the Back button doesn't work properly.
Anyone who doesn't support JS to the level you want? Well, fuck those people, let them make their own wheelchair ramps.
> If done properly (and that's a big if!), and where appropriate, this can be much faster.
A big IF, indeed.
For "application paradigm" my points stand. That's where JS is appropriate. I did say "where appropriate", after all.
> Primary and by far most frequent use case.
In document paradigm.
> And then you can never return to the same page again, it's gone into the either, and the Back button doesn't work properly.
Not if the client-side routing is done properly. I did say "if done properly".
> Anyone who doesn't support JS to the level you want?
With modern transpilers, you can produce lowest-common-denominator JS. Essentially you are treating JS as a build target / ISA.
> Well, fuck those people, let them make their own wheelchair ramps.
What's the alternative? They can download a native app, but that doesn't work for everyone either (both from the developer and the user perspective).
And not only is the stack you describe full of delays, several of the layers are outside of the control of the software in question and can just… fail! Sure, there are cases where I need my software to communicate with the outside world, but I get furious when some page with text on it dies because somewhere in a datacenter some NIC failed and thus the shitty webapp I was viewing fell over.
You were motivated by submitting a cool demo, they are motivated by not being fired after deadlines. An additional network hop is nothing compared to not shipping.
When I look at the massive backlog of requests from my users, not a single one is "speed."
I've recently come across several such applications that were "split up" for no good reason. Just because it's the current fad to do the microservices thing. Someone liked that fad and decided that over-architecting everything is going to keep them employed.
To clarify: This was strictly worse in every possible way. No shortcuts were taken. No time was saved. Significant time and effort was invested into making the final product much worse.
Can you tell what is your occupation? Are you dealing with assembler level programming regularly?
It just grinds me gears that we have all these wonderfully fast computers and we're just throwing the performance away.
My analogy to customers where I consult is this: What you're doing is like buying a dozen sticks of RAM, and then throwing ten of them into the trash. It's like pouring superglue into all but a couple of the switch ports. It's like buying a 64-core CPU and disabling 63 of those cores. It's like putting some of the servers on the Moon instead of next to each other in the same rack.
Said like that, modern development practices and infrastructure architectures suddenly sound as insane as they truly are.
To be fair, profiling is way more difficult than it was in the days of single-core local applications. A single-threaded single-machine application means you can get a very clear and simple tree-chart of where your program's time is spent, and the places to optimize are dead obvious.
Even if you're using async/await but are basically mostly releasing the thread and awaiting the response, the end-user experience of that time is the same - they don't give a crap that you're being thoughtful to the processor if it's still 0.5s of file IO before they can do anything, but now the profiler is lying to you and saying "nope, the processor isn't spending any time in that wait, your program is fast!".
Not if you graduated from the printf school of profiling[1].
Measure the time when you start something, measure the time when you finish, and print it. Anything that takes too long gets a closer look.
[1] unaffiliated with the printf school of debugging, but coincidentally located at the same campus.
Write a riddle for a CPU with 100% cache miss rate, confusing the prefetcher to clog the memory bus, and enforcing a synchronous memory access. Such thing is very likely to run literally with an MCU speed on an x86 PC CPU.
Nobody wants slow software, its just cheaper, in upfront and maintenance costs. Going with analogies, its like a race car mechanic complaining that a car is using like 3 cylinders where it could have 8. Sure but some people have other priorities I guess.
In theory yes, in practice this almost never happens. 95% of the teams just quickly mash the product together and peace out before anyone notices what mess did they make. And then you have some poor Indian / African / Eastern European team trying to untangle and improve it.
Seen it literally tens of times over a course of 19 years career.
> Nobody wants slow software, its just cheaper, in upfront and maintenance costs
That is true. But nowadays it's more like taking a loan from the bank and running away to an uninhabited island to avoid paying it off.
Much of my work is in highly parallelized computing (think Spark across thousands of nodes) processing 10s or 100s of TiB at a time with declarative syntax. It's super cool. Until someone decides they're going to use this one line expression to process data because it's just so easy to write. But it turns out doing that absolutely destroys your performance because the query optimizer now has a black box in the middle of your job graph that it can't reason about.
Bad practices like that occur over and over again, and everyone just figures, "Well, we have a lot of hardware. If the job takes an extra half hour, NBD." Soon, you have scores of jobs that take eight hours to run and everyone starts to become a little uneasy because the infrastructure is starting to fail jobs on account of bad data skew and vertexes exceeding the predefined limits.
How did we get here? We severely over-optimized for engineer time to the detriment of CPU time. Certainly, there is a balance to strike, no doubt. But When writing one line of code versus six (and I'm not being hyperbolic here) becomes preferable to really understanding what your system is doing, you reap what you sow.
On the plus side, I get to come in and make things run 5x, 10x, maybe even 20x faster with very little work. It sometimes feels magical, but it would be preferable if we had some appreciation for not letting our code slowly descend into gross inefficiency.
But time and time again I see that projects with a fast “enough” interfaces and flexible systems win out on more specialized, faster ones. And I hate that but here we are. Sometime we see a really performant piece of software hit the sweet spot of functionality for a while (for example sublime text) but then get overtaken by a fast enough but more flexible alternative (vacode)
Eastern European coders are highly competent, they did magic back in the day with just a ZX Spectrum.
Very few people enjoy producing junk, but management (and customers) often demand junk today rather than quality tomorrow.
>> most of those "primadona devs", as you call them, would much prefer to write well-designed programs cleanly coded
Most of them - yes. But there's a non-negligible chunk of them who are too careless or incompetent to care about quality - they've been around long enough to gain knowledge about project and get Vice-President title(inflated ego included).
It is especially visible in big banks (I suppose it's typical for other big non-tech corps as well) where tech culture is generally on poor side.
edit: grammar
Given the chance I'd likely collect a fat paycheck and bail out at the end of the contract as those other people did. But that attitude is responsible for the increasingly awful mess that modern software is becoming.
Almost everyone is at fault, me included. The perverted incentives of today's world are only making things worse.
I mean the web stack itself was never designed per se. HTML is essentially a text annotation format, which has been abused to support the needs of arbitrary layouts. The weakness of CSS is evident by how difficult it has been to properly center something within a container until relatively recently. And Javascript was literally designed in a week.
And then in terms of deploying web content, you have this situation where you have multiple browsers which are moving targets, so you can't even really just target raw HTML+CSS+JS if you want to deploy something - you need a tool like webpack to take care of all the compatibility issues, and translate a tool which is actually usable like React into an artifact which will behave predictably across all environments. I don't blame web developers for abusing libraries, because it's almost impossible to strip it all down and work with the raw interfaces.
The whole thing is an enormous hack. If you view your job as a programmer as writing code to drive computer hardware - which is what the true reality of programming is - then web development is so far divorced from that. I think it's a huge problem.
Now? You need Windows desktop, mobile on 2 different operating systems, web, MacOS, and possibly TV depending on your market.
What's the lowest common denominator? Web stack.
I only have a problem with the ones among those hammer only people that are proud of not knowing anything else and proclaim everybody not using a hammer for everything stupid, because "look on all those perfected hammers we created! your choice doesn't have such nice ones".
This stuff was fixed at least 5 years ago. If you can drop support for IE11 (released in 2013 and no longer supported by Office 365), you’ll find that framework-free web development has improved massively since React was first released. And if you keep it simple and rely on what browsers support natively, you can achieve great performance.
Rendering hundreds or thousands of meshes and doing complicated 3D math for physics is no problem, UI is still extremely hard and complex, especially if you are supporting multiple arbitrary resolutions for example.
Godot, for example, has a full UI toolkit built in (the Godot editor was made using Godot components). However to actually get it working the way you want in most cases is a horrendous struggle, a struggle with ratios, screen sizes, minimum and maximum UI control sizes, size/growth flags, and before it gets any more complicated please just throw me a Tailwind flex/grid box model instead, because HTML/CSS has solved these problems repeatedly already.
So responsive Electron apps are certainly possible.
1. It takes nine times as long as Vim to open a minified JavaScript file, and then format it with Prettier: https://twitter.com/robenkleene/status/1285631026648276993
2. It takes 14 times as long to open an empty text file than BBEdit: https://twitter.com/robenkleene/status/1257724392458661889
Both of the above examples revolve around opening files for the first time, and I suspect a lot of the slowness I perceive is because I open a lot of different projects and source code files when I'm working, and this is a bad use of VS Code.
In practice, VS Code behaves more like a multi-language IDE than a text editor. Slow startup times are generally acceptable in IDEs because you're exchanging speed for power. A programmer should ideally be proficient in both an IDE and a text editor, because they're tools applicable to different problems. E.g., VS Code is a terrible choice for things like analyzing log output, formatting large files, testing isolated snippets of code, or working on source code files that aren't part of the same project. I find this to be a shame because VS Code is flexible enough that it would otherwise be excellent for all of these tasks if it were just more performant for some operations that it struggles with now.
I would agree that VS Code isn't the fastest thing when the editor is starting up, though I find it fine when started. I pretty much always have VS Code running so I don't find this a problem.
A lot of the overhead seems to come from making a new window (even though the app itself is already running), although notably most of the time spent in the Prettier example seems to be spent syntax highlighting the JavaScript. If you want to try a direct comparison of opening a file vs. a window, you can see the difference between opening a new file in an existing window (on Mac, `⌘N` / `File > New File`) or new window (on Mac, `⌥⌘N` / `File > New Window`). For me the latter is far slower than the former.
The whole point for then from the start was to not to repeat the Atom fiasco.
The entirety of the project was running around of making Webkit not suck.
They spent ennormous effort on that.
I think it’s only noticeable if you’ve used a native application for a while. It’s not enough to go from VSC to Sublime and back to VSC again for five minutes. Make an effort to use a native app for a week or a month and then switch back.
Emacs will sometimes become slower (especially remote emacs), but it will always buffer your keypresses and do them in the correct order.
Jupyter (for whatever reason), doesn't do this with the result that I ended up wanting to create a new code block, but that keypress got lost and then i end up ruining my original code block.
I 100% noticed the difference, and it was super frustrating (fortunately I left that job, and have managed to avoid Jupyter in the new gig).
Emacs/Spacemacs can still be weirdly slow sometimes but UI responsiveness is generally miles ahead of all Electron-based software still.
Which makes it even funnier. Emacs is decades old and still uses quite a few ancient techniques that are only hampering it. Even with that, it's still so much better in terms of speed! Funny.
Yes, and no. They have a really interesting tale of convergent evolution.
Atom was the original Electron app (as pointed out Electron was even originally named "atom-shell"), so it predates VSCode as an Electron app. But the extremely performant "Monaco code editor" that VSCode was built on top of (that forms the heart of VSCode) was started at Microsoft years before to be a code editor in parts of the Azure Portal, and also it was the code editor in IE/Edge dev tools from as far back as IE 9 or 10 I think it was (up until the Chromium Edge). It wasn't packaged into an Electron app until after Atom, but it has an interesting heritage that predates Atom and was built for some of the same reasons that GitHub wanted to build Atom.
(ETA: Monaco's experience especially in IE Dev Tools and the wild west of minified JS dumps it had to work with from day one in that environment is where a lot of its performance came from that led VSCode to jumping Atom on performance out of the gate.)
I'm guessing it's pretty much dead now that github is under the same company that also makes vscode, right?
Well electron used to be called "atom shell" :)
VS Code also used to have far more native code earlier on in its development life, but seems to be transitioning a lot of it to WASM (paralleling the Node ecosystem as a whole moving a lot of performance heavy stuff from native NAPI plugins to WASM boxes; as one example: the major source maps support library moved from JS native to Rust to WASM compiled from Rust, IIRC).