Live data from Hacker News

Emerging Rust GUI libraries in a WASM world

monadical.com

191–200 of 272 posts

Re: Emerging Rust GUI libraries in a WASM world

#191

Earlier quoted context omitted.

Rust doesn't have to output more code than a C compiler. But it tends to because most rust programs are stuffed full of bounds checks. And bounds checks aren't small. As well as the conditional itself, every bounds check also includes: - A custom panic message (so you know which line of code crashed) - Some monomorphized formatting code to output that message - The infrastructure to generate a stack trace after a pan…

I'd appreciate any more tips or resources you might have about reducing Rust code bloat. I want my library [1] to be acceptable to the most strident anti-bloat curmudgeons, so they'll make their UIs accessible. [1]: https://github.com/AccessKit/accesskit

I don’t know many good resources to learn this stuff unfortunately.

The things I reach for in practice are godbolt and cargo asm[1] - which can show me the actual generated assembler for functions in my codebase. And twiggy[2], which can tell you which functions are the biggest in your compiled binary and point out where monomorphization is expensive.

When I’m developing, I regularly run a script which compiles my code to wasm and tells me how the wasm file size has changed since the last time I compiled it.

Some tips:

Try to avoid array lookups with an index when you can. When looping, use slice iterators and when making custom iterators, wrap the slice iterator rather than storing a usize index yourself.

Be careful of monomorphization. If you’re optimising for size, it can be better to take a dyn Trait rather than making a function generic.

And play around with your wasm API surface area. It takes a lot more code to pass complex objects & strings back and forth to javascript than other types.

But otherwise, good luck! Love the project.

[1] https://github.com/gnzlbg/cargo-asm

[2] https://github.com/rustwasm/twiggy

Re: Emerging Rust GUI libraries in a WASM world

#192

Earlier quoted context omitted.

Its certainly controversial. Using canvas based rendering like this is essentially reverse-electron. Electron builds native software by embedding a web browser and using the browser's layout engine and DOM. Canvas based rendering like this is the inverse. Here the application discards the browser's layout engine and DOM, and instead embeds its own layout engine. - Despite the browser being right there and available.…

The idea is that instead of shipping electron, you ship a native binary that use egui without using wasm or the canvas. Egui only use wasm in situations where you must use the user browser because you have no choice. Eg: showing a demo of the app on the web without having to install anything. > Its a 5mb wasm bundle. But on the plus side, 5mb is positively tiny compared to shipping electron This comparison makes no s…

> This comparison makes no sense. Situation where electron could be used are exactly the kind of situations where a wasm bundle would not be shipped (a native binary would be shipped instead)

Sure; but given the insane size of shipping chrome, it’s fun seeing a full app complete with widget library, layout engine and text input elements in 5mb. It’s terrible to make websites that big. But if chrome could do all that stuff in only a 5mb binary then I’d be much happier with electron.

If you didn’t catch it, the wasm bundle is running in a 32mb memory slab. Positively slim by the standards of modern gui apps!

Re: Emerging Rust GUI libraries in a WASM world

#193
post #188

Earlier quoted context omitted.

Like I said in my top comment, it's a profiler. I need to consume logs from distributed applications (on possibly tens of thousands of nodes) and render them in as coherent a fashion as possible. Going to 3d rendering via OpenGL / WebGL was one of the options I considered. But honestly, this is a boatload of complexity. Why do I need to pick up a full 3D rendering library just to draw rectangles on the screen? Plus,…

The reason to pick up a "a full 3D rendering library" is that it is actually a lower level interface to the hardware. Almost all 2D operations are now implemented on top of 3D hardware primitives. By limiting yourself to a 2D engine you're ensuring there are more layers of abstraction between you and the hardware. While # layers of abstraction doesn't always correlate with overhead, it does place limits on performanc…

Yeah. And it’s not one or the other. On the web you can make a “3d” rendering surface for the profile traces and use absolutely positioned DOM elements rendered on top for you hover-over widgets and things.

It’s still a bit of a mess though. I understand wanting to keep everything in a single UI library if you can.

Re: Emerging Rust GUI libraries in a WASM world

#195
post #105

Earlier quoted context omitted.

Of course you'll always have different ways of building UIs depending on circumstances but eventually some consensus will be reached for a default approach. WinForms used to be the default for Windows, Tk was the default for Linux (or at least that was my impression, I was all in on Windows back then), etc. For many people, using web tech has become the default if you want to build cross platform UIs. You have the op…

OSes that come with a native UI obviously have that as the default. But there will never be a default across OSes I think. Web UIs might be that, but I sure won't want to use html or js anywhere in my UI's if I can help it, even if cross platform. Java might perhaps be the best example of trying to make a default-for-a-language cross platform UI (Swing and whatever it was called that came before it). But I think it's…

Qt and Swing are pretty good at "not quite native but close enough" in practice, IMO. I would take either one over a web or Electron app that completely disregards native UX and rolls it own, which is typical of them.

Re: Emerging Rust GUI libraries in a WASM world

#196

Earlier quoted context omitted.

> I'm not sure Canvas can handle either part of this To be clear, WebGL/WebGPU is still using Canvas. You're not using the 2D api stuff, but that's just a high-level API on top of Canvas. You're still rendering to Canvas. > I don't know if you noticed, but my test has on the order of 10 billion rectangles Why? I've built apps like this before. Your choice is not "abandon the DOM" or "have zero performance." You can h…

If you build an equivalent tech demo in HTML Canvas, I'd be curious to see how it performs. I'm sure you're aware that, just because Canvas layers on top of WebGL/GPU draw calls, doesn't necessarily mean it's performant in the way I need it to be. There are many ways for performance to degrade across abstraction layers, even if in principle it shouldn't. I didn't test Canvas specifically in my explorations, but I did…

> just because Canvas layers on top of WebGL/GPU draw calls, doesn't necessarily mean it's performant in the way I need it to be

You are using Canvas right now. WebGL uses Canvas to render to the screen. If you open up your demo's DOM inspector right now, you will see a canvas element. It's:

  
It's a little bit hard for me to trust this kind of dismissive talk about the browser adding too many abstraction layers when it's not clear to me that you're fully aware of what browser features your demo is using right now. Targetting the DOM and using embedded canvases really doesn't have anything to do with whether or not you're writing Javascript, and it doesn't mean you can't use WebGL to render charts.

Re: Emerging Rust GUI libraries in a WASM world

#197
post #108

I hope it's OK to add a shameless plug for my Rust WASM framework, Silkenweb [0]. It's similar to Leptos and Sycamore in that it's signals based, but I've put a lot of effort into making it ergonomic without resorting to a macro DSL. It supports all the usual things like SSR and hydration, along with a few nice extras like scoped CSS. [0] https://github.com/silkenweb/silkenweb

While I'm usually a no-macros kinda guy, but (I believe) leptos and dioxus provide tooling to hot-reload markup-only changes without (incremental) recompilation. Do you think that would be possible withour macros?

Re: Emerging Rust GUI libraries in a WASM world

#198

What's wrong with TypeScript? Last time I checked all WASM stuff was slower and much heavier than TS/JS.

> What's wrong with TypeScript.

I love typescript, but, from my PoV, what I miss in typescript is:

- An actually sound type system: This is a big one. Can you figure out why this[0] is unsound?

- I regularly have to do `as ` assertions, and I know it's not because I'm bad at typescript because it's often the recommended solution from cream-of-the-crop tS libraries for certain issues.

- Traits

- new-types

- Algebraic data types: Option and Result. 'nuff said.

- Pattern matching: :cheff's kiss:

[0]

    export function useSetter(
      state: T,
      setState: (n: T) => void,
      key: K
    ) {
      return useCallback(
        (val: T[K]) => setState({ ...state, [key]: val }),
        [key, setState, state]
      );
    }

Re: Emerging Rust GUI libraries in a WASM world

#199

Earlier quoted context omitted.

If you build an equivalent tech demo in HTML Canvas, I'd be curious to see how it performs. I'm sure you're aware that, just because Canvas layers on top of WebGL/GPU draw calls, doesn't necessarily mean it's performant in the way I need it to be. There are many ways for performance to degrade across abstraction layers, even if in principle it shouldn't. I didn't test Canvas specifically in my explorations, but I did…

> just because Canvas layers on top of WebGL/GPU draw calls, doesn't necessarily mean it's performant in the way I need it to be You are using Canvas right now. WebGL uses Canvas to render to the screen. If you open up your demo's DOM inspector right now, you will see a canvas element. It's: It's a little bit hard for me to trust this kind of dismissive talk about the browser adding too many abstraction layers when i…

> You are using Canvas right now. WebGL uses Canvas to render to the screen.

Ehhh sort of. Canvas is much older than webgl. When we talked about canvas a few years ago, that always referred to the canvas DOM element and its associated 2D shape based API. (fillRect / moveTo / lineTo / etc). When Webgl appeared, the nomenclature was "using canvas" vs "using webgl", since webgl's API is completely different from the 2d canvas API.

But browser manufacturers didn't give webgl its own DOM element. Webgl also uses a canvas DOM element, then configures it differently. (getContext("webgl") instead of getContext("2d")). So if you're using webgl (which I think this app is doing), then you're "using canvas" in the sense that your HTML contains a element. But you aren't using the canvas 2d API - which, as I said, is totally different from webgl and is also called "canvas" because it was here first. And it doesn't have another name.

In defence of the GP comment, I think its pretty clear from context that "Canvas layers on top of WebGL/GPU draw calls" refers to the canvas API, not the canvas DOM element.

Re: Emerging Rust GUI libraries in a WASM world

#200

Earlier quoted context omitted.

What domain are you working in? Smoothly rendering 3k rectangles isn't a common use case for UI libraries, so I'm not surprised they perform poorly. They generally aren't optimized for that. The normal answer for weird, high performance rendering like that is to just use opengl or something and program against the GPU directly. 3d rendering contexts can render millions of rectangles on modern hardware without breakin…

Like I said in my top comment, it's a profiler. I need to consume logs from distributed applications (on possibly tens of thousands of nodes) and render them in as coherent a fashion as possible. Going to 3d rendering via OpenGL / WebGL was one of the options I considered. But honestly, this is a boatload of complexity. Why do I need to pick up a full 3D rendering library just to draw rectangles on the screen? Plus,…

I was curious so I took a look at firefox's profiler. It looks like it does a hybrid render, using a couple of canvas elements for the flame graph and the stack trace (up the top), but the rest of the UI is rendered using plain old DOM elements. It performs great, despite the whole thing being pure javascript.

Example: https://share.firefox.dev/40QUthv . (Though this trace is probably smaller than the profiling traces you're demoing.)

Post reply on HN