Compile times generally take longer with Rust. It's a trade-off you're making when using anything rust related, but in exchange, you get some pretty sweet runtime perf. But with efficient caching of crates you can claw back a lot of time in CI.
doesnt that determine runtime performance for web apps, unless the browser is running rust natively or maybe wasm, I don’t see how javascript for example would be more performant just because I configured it in rust
That's very kind of you, thank you! Yes the goal is to make it usable in production! It already powers proa.so, ui.proa.so, latency.so, and a few other sites. Let me know when you build it and I can add it to https://proa.so/ecosystem/apps!
> This might be a silly question, but why 2 views for html and markdown?
No such thing as silly questions! Yes there are cases where it can be inferred from one to the other, but in many cases you may want to be very specific about how you author the markdown view. I'll give you a few examples:
1. Custom components: For example, let's say you have a carousel component. It's not really straightforward to infer the markdown from this. But you probably want the carousel to render as a series of markdown image tags. A custom view would be helpful for this. Same goes for Calendars, SVG charts, Diagrams, form inputs, tabs, popovers, and more.
2. Information omission: Agents don't need all of the information on your page. For example, a dark/light button... probably doesn't need a markdown equivalent. But a button that is an anchor tag that links to another page, probably you should keep. So having the ability to custom author the markdown render target based on the data it's rendering is helpful.
One of the unique aspects of Proa's authoring model is that it supports composability of Markdown components, just like JSX, which is I think one of its standout features. And you can embed native control flow (if, loops, match, etc.) directly in the md!{} macro just like you could with JSX. https://www.youtube.com/watch?v=pJx84jdBDKU&t=21s explains it quite well if you're interested. Makes the readability and code ergonomics much much better.
> it's exciting to see so many rust web frameworks popping up but I'm in total decision paralysis.
I am a bit biased here but I think Proa is the most complete framework currently for building a production web application in Rust. I know its newer and doesn't have as many stars, but maybe I can point you to three things to see if it gives you more confidence:
Proa, Proa UI, latency.so, and a few other sites are all using Proa in production. It's the fastest SSR framework in production (https://github.com/Proa-Labs/proa-benchmarks) and supports streaming SSR (checkout the streaming SSR benchmark), suspense, etc. And it's server framework agnostic so you can use it with actix, axum, and other frameworks if you want.
Ah ok so it's more of the ui layer? because when I look at for instance loco, it handles background jobs, emails, auth - it's a battery included framework. So proa is something that could be used in place of askama + htmx but still with another full featured (or totally minimal) framework?
It's funny, my first thought with multiple render paths was specifically for htmx integrations... Such as a full render or just a main component render. There are extensions for C#/razor that with really well for this.
Would be cool to do the same with rust. That said, I didn't know how hard that would be with this framework. There are of course a lot of different limitations with ssr vs soa.
I highly recommend! I've been writing Rust professionally for 5 years now. Compile times are slow but I love the language. https://cheats.rs/ is a resource i go back to often in case you're interested in learning more. Especially since as you get more into it, Rust has a lot of weird types like RefCell and Cell and OnceCell and disambiguating between them is a chore sometimes. Hope it helps!
I can't speak for the others as I am not as familiar with how they're engineered, but with Proa I spent a painstaking amount of time to try and move as much of the work to compile time as possible and being really careful about how memory is allocated. And a lot of those small improvements add up over time!
Hey great question! WebContext owns an output buffer (i.e., RenderBuffer) that components write HTML into directly, avoiding intermediate allocations and copying. It needs to be mutable for this reason. This is one of the key ways we're able to make Proa the fastest server-side rendering engine on the market.
By default, WebContext composes RenderBuffer (but it can be overriden via generics) which uses fixed-size 4 KiB pages. When a page runs out of room, it adds another page without moving the HTML already written. This avoids copying the accumulated output during growth! Its designed to be a performance improvement over Vec<u8>
For context, the problem with Vec<u8> is that every time a vector reaches maximum capacity, it has to reallocate a new area of memory (typically 2x larger than the previous allocation) and then copy everything into that new buffer. This adds a ton of overhead, especially if you're writing large pages.