> But Java is slow and heavy? [in the context of JSF/PrimeFaces and others]

Yes, with the setup of JSF and PrimeFaces, my experience has only been negative, both in regards to resource usage, performance and developer experience.

Maybe not for smaller projects where your requirements are relatively simplistic, but once you're working on a huge monolith that has been around for 5+ years and has hundreds of forms, with nested components and lots of partial form updates and form state, absolutely - the experience is hot garbage.

You might say that I've just worked on a bad codebase and I'd wholeheartedly agree, however in my eyes that's essentially the inevitable end point for how this entire technology stack will evolve in live codebases: a downwards trend towards hard maintainability and everything breaking.

For example, it might be because you put <p:commandButton/> inside of a <p:panelGrid/> directly instead of a <p:outputPanel/>, but only the layout will break initially (and not always in obvious ways), yet the form state will be lost on tab navigation and will give you cryptic errors because your TabChangeEvent has null in the new tab field.

Or maybe you'll need OmniFaces to handle validations but those won't play too nicely with <p:growl/> or any of the auto update logic, or maybe you'll find yourself struggling with PrimeFaces selectors because you just need to update a single row in a table that has components inside of it, as opposed to the whole table because that would be too slow, but won't be able to do so efficiently because somewhere along the way half of the ID will be generated dynamically but CSS selectors won't work properly either for some silly reason.

Or maybe you'll run into problems where you must restructure your form because you cannot put certain elements such as modal dialogues inside of components that will be updated with AJAX thanks to some of the state being lost otherwise and sometimes the modal dialog flashing when things elsewhere in the form are updated.

Even better when it won't play nicely with any other JS libraries that you might need because of project requirements, like custom calendar widgets or time pickers, or anything of the sort. Oh, and good luck integrating it with the rest of the application, serving static resources, figuring out all of the servlet related configuration, as well as scaling it, especially horizontally with multiple instances needing to share server side state information.

I've actually written about some of the things previously: https://news.ycombinator.com/item?id=32071817

In short: my experience might be completely the opposite of many of the folks here, but if I see JSP/JSF/PrimeFaces/OmniFaces (and to a lesser degree, GWT or Vaadin), I'll run for the hills. I've had universally better experiences with Vue, React (even with hooks), Angular, and even jQuery back in the day. Actually, I think the only thing worse than the Java front end setup was Angular.js but maybe that was also due to a badly commented and bloated codebase.

Instead, consider serving a React/Vue/Angular SPA app with Nginx/Apache/Caddy. Have a separate API as a self-contained Java/.NET/Node/Go/Python/Ruby/whatever executable/container. Set up a reverse proxy for SSL and any path related manipulations and live without having to stress over brittle architectures. Keep it simple and stay away from overengineered technologies.

(disclaimer: I'm biased, server side rendering can also be pretty reasonable, e.g. Ruby on Rails, or perhaps a slightly better implemented setup with other stacks than what I've seen)