Comment by james2doyle
2 hours ago
I actually tried to use HTMX on a site recently. I used the 4.0 beta. The site needed an interactive filterable product-listing-page-type experience to list out all their vendors. Form filters on the left and the list of results "cards" on the right.
The problem I had was that the entire experience became really slow when I had it all working together as one "response". Sending back all that HTML for an entire form with some large select lists as well as the response of results became noticeable laggy when there was more than a half dozen results.
I ended up switching to Alpine Ajax (https://alpine-ajax.js.org/) and pulled the form out of the response and just used a local x-data on it to track the state. This greatly reduced the HTML I needed to send back to just the list of results. I did make the form a bit more complicated but the experience felt a lot snappier. Both versions just synced the form state from the URL and kept the initial render as full HTML from the server.
I found that Alpine + Alpine Ajax was SMALLER than HTMX 4 even though (in my opinion) it offers a lot more features in a more approachable and intuitive way if you need to do interactivity and don’t want to trigger a request just to toggle some classes or attributes. Of course you can use both together (I started down that road) but you are mixing worlds and making the bundle size bigger at the same time.
I still like HTMX and will probably use it again. I just found that with an interactive experience like a product listing page, where the HTML response was quite large/expensive to fetch, it wasn’t the best choice for that.
You can always make the server-side render partials based on a request header.
https://github.com/dsego/ssr-playground/blob/main/src/server...
That is what I did. I was using Astro which has full support for partial HTML via the router
I think I understand now, even the partial required submitting everything to the server, which can be skipped if you can have interactivity without unnecessary requests.
1 reply →
AJAX is old tech though, using stuff that worked in the year 2000 is cheating in 2026. You are supposed to make the site slow and bloated for some reason.
Is there a reason why you don't have an endpoint + template that renders only the result list. The form could be separate thing and issue a form submit request with all the selected filters? Seems better than rendering the whole page. You could even display a loader while the results are loading, and swap the list html element on success.
have a look at https://segor.de/ - it just downloads 2MB of product listing data (pre-dating JSON!) and then does all filtering client-side
[dead]
You swapped out HTMX because you couldn’t figure out how to load a list of items gradually instead of all at once??
If I wanted to do that I would have added pagination. But that UX also sucks in a different way.
I think dynamically fetching results (ala infinite scroll) would have been more complicated to build. I would have had to add an intersection detection (HTMX 4 has that) to trigger the form/request again, but with an ever increasing chunk offset slice. I also need a way to track that state as well. Considering I had one big HTML response, I don’t think I could have done that efficiently without splitting it anyway. Even if I could "pluck" the results I needed from the HTML response, the penalty of waiting for the response was the factor.
If you have any links to some demos where there is something like that, I would appreciate it.
All that being said, the count of items actually isn't the most relevant part. The most relevant part is the amount of HTML per single result. If you have a sophisticated card component (a title, a description, images, a table of information inside of it or complicated layout) just loading six cards could end up being hundreds of HTML elements.
So even if you lazy loaded elements in chunks, those chunks are still gonna take a while to fetch given the size of the HTML. You also break CTRL-F-ing since those results don’t exist in the DOM until you trigger their fetching code. Same problem as classic pagination.
I would have to completely refactor my entire experience regardless because if I want to lazily load the cards/results gradually, I would have to split up the layout to make it more efficient.
So my approach to shrink the HTML response was to break it up the "live" section to just the right half.
Want to help rather than throw tomatoes?
Wouldn't constantly loading new items into a select form be super annoying? Can HTML even keep a select input open when new items are added?