7 ms·
I've been building a profiler UI in egui recently, and have been pretty happy with it. I didn't try out all of the options in this article (there are rather a l
by eslaught 3y ago
I've been building a profiler UI in egui recently, and have been pretty happy with it. I didn't try out all of the options in this article (there are rather a lot of them), but I did try several, and out of the ones I tried, egui was by far the highest performance. Since my goal is to shove as many rectangles onto the screen as possible, this was the killer feature for me, but it was also nice that it did most of the other GUI stuff I needed.
WASM demo here if you want to see it (with dummy, and not particularly realistic, profiling data): https://elliottslaughter.github.io/legion-prof-viewer/ https://elliottslaughter.github.io/legion-prof-viewer/
For comparison, the UI I'm replacing falls down with about 16 nodes worth of data. (The demo has 8192 "nodes" worth of fake data.)
- josephg 3y agoCool demo, but by the looks of things the whole site is rendered into a canvas element. As a result, the browser's dev tools are useless, it won't work with screen readers, and you can't copy+paste text. And any text rendering and input elements will be non-native. (So, no nice iphone controls. No native / system configurable keyboard shortcuts. And so on.) I sincerely hope the web as a whole doesn't move in this direction. The inspectibility of the DOM is one of the web's greatest strengths. Lets not throw that away.
- deleted 3y ago[deleted]
- chrismorgan 3y agoAnd scrolling is unavoidably all wrong: dragging two fingers from one end of my touchpad to the other should scroll by about four screenfuls, but only manages two thirds of one screenful; a quick swipe should send it dozens of screenfuls, with inertia, but manages even less than that two thirds of a screenful; and these limitations are fundamental due to the web not possessing the right primitives. (Then there are more fixable bugs like that, after focusing the page, you have to move the mouse before scrolling will work.) And input element behaviour is non-native, which will never be properly fixable since different UAs have different behaviours, some of which cannot be emulated even if you sniff which platform you’re on (e.g. scroll bar grab and drag behaviour when you move far outside the window). (Then there are also simple bugs: holding Left or Right while the range element is focused only bumps the value once, not according to key repeat. And Up and Down don’t work.) I have written about these things a number of times, fundamental limitations of the pure-canvas approach that make it unavoidably and permanently unsuitable. https://news.ycombinator.com/item?id=33861831 https://news.ycombinator.com/item?id=33861831 is probably the best thread. (And just for a bit of fun: the demo can have slightly negative utilisation, drawing outside the box!)
- eslaught 3y agoIn my testing, I went through a bunch of Rust frameworks that sit on top of the core OS UI frameworks. My experience with all of those was that they all capped out at about 3k rectangles on a screen at a time at 30 fps (vs the about 80k rectangles that fit at usually 30-60 fps in my demo). I wonder if your experience is different? As best I've been able to tell, right now you have to make a choice between (a) fast and (b) native, and you only get to choose one. And in my application domain, fast is nonnegotiable.
- mtsr 3y agoMixed UIs could probably work well here. Using a canvas and specific gpu rendering just for the part requiring high throughput makes sense.
- josephg 3y agoWhat 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 breaking a sweat. This advice is the same on desktop, mobile or the web. I'm not surprised rust UI frameworks have the same limitation. Most UIs don't need thousands of rectangles. But they do need lots of custom widgets, and implementing all of those well is a higher priority job for anyone building a custom UI library.
- eslaught 3y agoLike 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, consider: the slot viewer (where the rectangles are shown) still needs to draw some UI components (e.g., on hoverover). I still need that UI integration there, even if it's not as performance-sensitive. So I end up needing something along the lines of egui anyway. I definitely understand that not all UI libraries are going to be optimized for this. But I was surprised that it wasn't easy to e.g. get a high-performance canvas dropped into libraries that specifically advertised themselves as high-performance.
- eslaught 3y agoI have no beef with deferred mode GUIs except that I have yet to see one with the performance characteristics I need. For what it's worth, egui does have an accessibility layer. I haven't gone to any particular effort to wire it up yet (besides what you get by default): https://github.com/emilk/egui/issues/167 https://github.com/emilk/egui/issues/167
- danShumway 3y agoThis is what I don't get: if you have an accessibility layer that is fully usable, that means you have the capability to describe your user interface using only speech/text. So what are you doing that couldn't be performant in the DOM? Because any kind of fast updates that you're doing with a lot of triangle that are too fast to render into an XML tree are also going to be happening too fast to describe with a screen reader. The DOM is asking you to be able to describe your interface -- performantly -- in entirely pure text. If you can't do that, then there's no way you can be fully accessible, because the screen reader needs to be able to describe your interface -- performantly -- in entirely pure text.
- danShumway 3y agoPeople always get upset about this kind of thing, but it's very obviously true. If you are updating thousands of rectangles in your UI at 30/60fps, it is impossible for you to fully convey the same amount of information that is changing visually to a screen reader. Either your interface can be described using pure text, or it can't. Either I could use your interface by closing my eyes and having someone describe it to me, or I can't.
- keyle 3y agoThat's nothing new with immediate rendering... You can't have great performance and great usability. Not saying I prefer that way, just pointing out the obvious.
- flohofwoe 3y agoIf the web API zoo wouldn't be so random it would all be easier. Pretty much all problems on the web (including the Javascript framework churn) are caused by the DOM being too high level, too inflexible and generally too 'black-boxy' to do anything interesting. Accessibility could be fixed easily if there would be a web accessibility API. There's basically an entire 'middle layer' of web APIs missing, current APIs are either too low level (like WebGL/WebGPU) or too high level (like the DOM).
- zkldi 3y agoyou're almost describing flash i mean, it sucked, but it was kind of that middle layer.
- danShumway 3y ago> Accessibility could be fixed easily if there would be a web accessibility API It does have one. The DOM is the web accessibility API. A really big point of the DOM is that you don't get to make multiple interfaces, you have to make one interface that works for everyone, which forces you to provide some degree of feature parity between those interfaces. The web accessibility API is "you have to describe your interface to us in pure text, because that format is more likely to be accessible."
- amelius 3y agoWe could build a "DOM" inspector that runs inside the canvas too ;)
- kps 3y ago> I sincerely hope the web as a whole doesn't move in this direction. I'm not happy about it, but I think it will. > The inspectibility of the DOM is one of the web's greatest strengths. Not if you're pushing ads.
- echelon 3y agoObligatory jaw-dropping egui demo: https://www.egui.rs/#demo https://www.egui.rs/#demo Egui slaps and is clearly going places.
- tristanMatthias 3y agoGot this to crash by change the font size in the font book demo.
- vincnetas 3y agoTrying to copy/paste in safari also crashes the demo.
- Animats 3y ago"Loading..." I've run it before. I know what it looks like. I use egui. It's OK. But you have to code up all your dialog boxes in Rust. This is misery if you have fifty dialog boxes and widgets you need. The widget library is weak and the themes are poor. I don't care, because I'm doing a metaverse client, and all the visuals are in the 3D image. The 2D GUI on top is minimal, as is normal for games. So minimal that it disappears completely, like YouTube controls, when you're not using it, to give you a clean 3D world. (Egui hint: don't use bottom-up layout. Always work top-down, left to right. Egui layout is one pass, and while it tries to look ahead, it's not good at it.)
- potamic 3y agoIt's pretty lagging for me on a beefy machine with hardware acceleration enabled. What gives?
- flohofwoe 3y agoAre other WebGL demos also slow (e.g. check https://webglsamples.org/ https://webglsamples.org/)? How uptodate are your graphics drivers? In some rare cases WebGL is blacklisting old drivers if they have known vulnerabilities, and instead falls back to software rendering.
- 3y ago
- rkagerer 3y agoThanks! I don't like how those textboxes get bigger when you click into them.
- osener 3y agoWhat makes egui so fast? I thought immediate mode GUIs have a convenient API at the expense of unnecessary redraws and lower performance. Would it be faster than iced or Slint at rendering scrollable list with thousands of rows with images and text? For the sort of use case you’d use a “virtualized list” implementation for React for example.
- ocornut 3y agoAlso try mouse-wheeling in Tracy web version (using Dear ImGui) and opening different panels: https://tracy.nereid.pl/ https://tracy.nereid.pl/ I think you'll find it to be more reactive and snappier than most traditional toolkits.
- flohofwoe 3y agoThis demo produces only a handful of draw calls to the GPU, and even though those draw calls can have hundreds of thousands of triangles, that's still as efficient as it gets. I guess that egui works similar to Dear ImGui: only (font) texture changes and clip regions (e.g. scroll areas) require a new draw call, and that's typically just a handful to a few dozen draw calls even for complex UIs. For long lists, Dear ImGui has a special 'ListClipper' class which allows to iterate over the visible 'slots' of a list, so that the code which describes the list UI can skip clipped items early. Not sure if egui has something similar.
- Freaky 3y ago> Dear ImGui has a special 'ListClipper' class which allows to iterate over the visible 'slots' of a list, so that the code which describes the list UI can skip clipped items early. Not sure if egui has something similar. An egui ScrollArea can request only visible rows from a callback using show_rows: https://docs.rs/egui/latest/egui/containers/scroll_area/struct.ScrollArea.html#method.show_rows https://docs.rs/egui/latest/egui/containers/scroll_area/stru...
- ReleaseCandidat 3y agoI understand that this is a demo, but actually drawing all 8,000 nodes instead of just 3 screenfuls (6 nodes on my screen) and updating them dynamically when scrolling isn't what I would call 'performant', but needless waste of resources. Btw: when clicking any 'task' to get to see the details, I see a repeating pattern of almost vertical stripes in some colors. I guess that's not what it should look like.
- birracerveza 3y agoIf drawing all 8000 nodes consumes less resources than rendering your average homepage, is it really wasteful? I understand it can be optimized, but that optimization often comes at a cost which may end up being even more wasteful.
- galangalalgol 3y agoYeah, when a gpu is involved it is often cheaper to process everything rather than check what meeds to be processed.
- ReleaseCandidat 3y agoI don't know how egui or the OP's app works, but we aren't talking about costly intersections of arbitrary surfaces but the sending of vertex data (for the vertex shader) in an integer interval (of nodes). This isn't about half or 1/10, but about 1/1000th of the data.
- ReleaseCandidat 3y ago> If drawing all 8000 nodes consumes less resources than rendering your average homepage, is it really wasteful? That may not have been clear, but I am talking about drawing less nodes in any case, also when using egui.
- flohofwoe 3y agoIn Spector.js it looks like the demo is using a very small number of draw calls, and those can sometimes have hundreds of thousands of triangles. For old low-end mobile GPUs this might start to become a problem, but it's nothing for the last 20 years of desktop GPUs. In any case, it looks like a good base for further optimisation to ignore offscreen UI elements early (e.g. not sure if egui has something like Dear ImGui's ListClipper).
- LeanderK 3y agowow, i am genuinely impressed! super snappy. I wonder whether it could be used to tackle a real pain point of mine. I work a lot with data, visualisations with jupiter notebooks. There are essentially two approaches: matplotlib, which outputs pngs/svgs. The notebooks stay fast but they are not interactive. The other is approaches like plotly, js-based, interactive, very useful but it gets slow really fast. I can not handle a lot of data. It can not handle a lot of plots. A simple, interactive plotting library with a focus on speed would be immensely useful! With python bindings. Could be a fun weekend project. I don't know any rust though, anybody up to collaborate? :P I bet the canvas approach would not slow-down the notebook.
- superdimwit 3y agoTry dear-imgui + implot. There are Python bindings
- ivoflipse 3y agoCheckout fastplotlib, which should be quite capable of what you're after and it works great in a Notebook https://github.com/kushalkolar/fastplotlib https://github.com/kushalkolar/fastplotlib Alternatively, try pygfx for ThreeJS graphics in Python leveraging wgpu. It works great in Notebooks through notebook-rfb. https://github.com/pygfx/pygfx https://github.com/pygfx/pygfx If you're adventurous, figure out how to make pygfx work with webgpu via wasm
- eslaught 3y agoIt sounds like you want BokehJS. It was one of the alternatives I was recommended while I was exploring, but for various reasons my particular use case is not so easy to integrate (plus my backend was already in Rust). https://github.com/bokeh/bokeh https://github.com/bokeh/bokeh I did do a basic test, and the raw rects-on-screen performance is roughly comparable to my final solution.