Hacker News new | ask | show | jobs
by mike_hearn 1175 days ago
There's a lot of space between rendering text and doing a slow remote database query. HTML is great but it just wasn't designed for building efficient UIs:

• No multi-threading, by implication you can't do things like deserialize large object graphs on a background thread. To get data to your UI you have to deserialize it on the UI thread, leading to jank.

• JS is a JIT compiled dynamically typed language. The memory overhead compared to C++ or even AOT compiled Java is correspondingly higher.

• DOM/CSS are extremely generic because they have to satisfy both document and app use cases. They're both low and high level simultaneously. On one hand that's great for making interactive documents - an important class of thing that non-web tech mostly ignores - on the other hand it means a lot of branches in hot paths, stringly-typed everything, big code footprint in the renderer, heavy objects, high level libraries can't use shared memory and more. The header file for Blink's DOM Element class is ~2000 lines by itself.

• No modularity whatsoever at any level. HTML just accretes more and more stuff as the years go by. There's no way to opt out, or select a lighter weight faster renderer. As it grows, memory usage and CPU time goes inexorably upwards despite fantastically huge budgets thrown at optimizing it.

• The one-size-fits-all sandboxing model imposes enormous overheads. Do I really need apps from well known brands like GitHub or Slack to be strongly sandboxed? Not really. It's nice to have a safety net in case of exploits, but I don't actually need these apps to be treated as radioactive all the time and the cost of doing so is very high. Native apps can use the latest DirectX on Windows, where hw features appear first, but Chrome serializes OpenGL command streams from the renderer across process boundaries and then does extensive validation before rendering them.

• JS was never designed for large teams. Why did Java become so popular in the enterprise? Because it has lots of rules and features that are intended to let lots of devs work together without stepping on each others toes or making too much of a mess. JS doesn't have the same approach.

It all adds up!

1 comments

So I don't disagree that this space has grown more organically than some, but I think most of what you've put there is fairly outdated.

> No multi-threading, by implication you can't do things like deserialize large object graphs on a background thread. To get data to your UI you have to deserialize it on the UI thread, leading to jank.

This is completely untrue today. I have a variety of ways to move work out of the UI thread as just a simple website. The easiest is to just use a modern networking API like fetch. If you're using response.json() on the result of a fetch call, you're done. The parsing is already off the UI thread by default.

If you don't want to do that (or you have a use case that's doing heavy lifting that's not a network request), you can easily add a serviceWorker and hand off the parsing to that JS context.

If you're on a browser that doesn't support serviceWorkers, you can simulate a similar handoff through framing your page (each page is getting a new JS context) and passing data around with postMessage.

If you're targeting Electron specifically - they start with the concept of a background worker (main) that is independant of the UI thread in the first place. It's easy to move work there.

----

> JS is a JIT compiled dynamically typed language. The memory overhead compared to C++ or even AOT compiled Java is correspondingly higher.

This is true but not really relevant. If you really need to be doing something with high overhead - electron allows you to easily call into native libraries, but you risk losing compatibility.

---

> DOM/CSS are extremely generic because they have to satisfy both document and app use cases.

I see this as a plus. DOM/HTML/CSS have literally been put through the ultimate trial by fire of use cases, and they are still standing.

---

>No modularity whatsoever at any level. HTML just accretes more and more stuff as the years go by. There's no way to opt out, or select a lighter weight faster renderer. As it grows, memory usage and CPU time goes inexorably upwards despite fantastically huge budgets thrown at optimizing it.

This is exactly what <meta> tags are for. They absolutely allow you control over the rendering process. Everything from specifying how to handle viewports to choosing the exact version of legacy IE you might want to target.

---

> The one-size-fits-all sandboxing model imposes enormous overheads. Do I really need apps from well known brands like GitHub or Slack to be strongly sandboxed? Not really. It's nice to have a safety net in case of exploits, but I don't actually need these apps to be treated as radioactive all the time and the cost of doing so is very high. Native apps can use the latest DirectX on Windows, where hw features appear first, but Chrome serializes OpenGL command streams from the renderer across process boundaries and then does extensive validation before rendering them.

I would argue that when the sandboxing is cheap, there's no reason not to use it. There's a reason that most enterprises allow their users to browse the web at large, but heavily restrict installed applications. Just from a bureaucracy and politics point of view, the sandbox is a plus.

---

> JS was never designed for large teams. Why did Java become so popular in the enterprise? Because it has lots of rules and features that are intended to let lots of devs work together without stepping on each others toes or making too much of a mess. JS doesn't have the same approach.

Yes, yes it does. It's called Typescript. Overkill for a single person project, but really freaking powerful for teams. Does exactly what you're describing - makes refactoring easy and safe, and allows teams to coordinate effectively.

------

It does add up, but it sounds like it's been a long time since you've done real work in this space. It's definitely not the same as it was 15 years ago, and while some of that change is probably churn, a lot of it is valuable additions that address nearly every complaint you've come up with.

A quick response:

1. Deserializing stuff in a service worker then requires it to be moved across to the main UI thread but you can't share the objects, right? It's message passing.

2. We're comparing to 'native' apps, right, so memory overhead of common things counts and saying you can use native code isn't really a rebuttal because you can't use it for the UI stuff.

3. We're not talking about how battle hardened they are, but about performance.

4. Meta tags have hardly any impact on the modern web, right? That's why you have to talk about legacy IE, they did try something like that but Chrome has no equivalent.

5. Sandboxing isn't cheap performance-wise, that's my point.

6. TypeScript isn't JavaScript, it's a different language that browsers don't understand.

I'll just respond to a couple of these:

1. I don't know if any of the major browsers do this, but one could imagine an implementation of that message passing, between threads or processes on the local machine, that has much lower overhead than deserializing from JSON.

6. If we assume that non-trivial web frontend projects these days always have a build step, then it doesn't matter; TypeScript compilation can be included in that build step.

Sure, and TypeScript is great, but I was talking about HTML rather than HTML plus all the layers people have added on top.

I'm also not totally convinced Typescript actually answers the point in question. It's a superset of JS in the end, and a part of why Java/C# type languages are popular in the enterprise is the list of things you can't do. Adding types can help, but it's not something that TS can enforce.