Introduction to Stimulus Reflex Discussion
woooooo... this is sooooo cooool. Thanks Chris for all the good content you giving us 👏.
You making likes Rails every days. Respect 🙏
That is incredible. I haven't used ActionCable or stimulus yet, but this makes me want to!
Will this work out of the box with Cancancan?
Awesome! Yes, please more videos. I'd love to use this in places where frameworks like Vue might be overkill. And I love anything that keeps me in Ruby/Rails land.
I like it!
notes on the new site design:
the completed tick needs to be heavier font, i can't really see if it's green.
set alt text on the buttons, i don't know what they all do. what does the text one do? alt text could also confirm completed status.
I agree! Just didn't have a better SVG to work with at the moment. Also going to add some tooltips.
Yep! I've got some fixes incoming for that. I just didn't have a better SVG to work with for the check at the moment and I wanted to ship what I've got.
This is really awesome! Yes, please do more videos on Stimulus Reflex. Would love to see how you do a drag-and-drop on the list and other cool client-side interactive tricks.
I'm interested if this will become the defacto/recommended way to build modern rails apps (the "view source" way, https://m.signalvnoise.com/paying-tribute-to-the-web-with-view-source/)....
Does anyone know if stimilus_reflex has gotten any love from the rails core team (or basecamp)?
this looks so cool. Thank you for the great content
@Chris, since stimulus reflex is using
action_cable behind the scenes which relies on a redis DB, do you have any idea if there are scale limitations for using stimulus reflex? ie, 1,000 concurrent users probably fine, but 100,000+ it starts crawling because redis is backed up, etc...
My understanding is that the default
action_cable implementation had some scale concerns, and that's why
any_cable (https://github.com/anycable/anycable) re-wrote some of the API in a faster language (I think they're using Go-lang?). I haven't encountered these scale issues in my own apps, so my knowledge is only "what the experts say", not based on real numbers.
I'm curious about the "production" viability of stimulus reflex before considering implementing in some of my systems.
Awesome video as always, and I'm looking forward to seeing more videos on stimulus reflex, keep them coming!
Hey Chris! I'm pretty new to a lot of the JS world so this is a bit of a general question but do you have a rule of thumb or a general guideline for what sorts of functionality you would leverage rails ujs vs stimulus js vs stimulus reflex? I'm building out a new platform so just trying to wrap my brain around the different objectives these help with... great video, thanks for all you do!
Not quite yet. For example, I'm trying to build a Trello clone with Stimulus Reflex right now. Everything works great, however when I try to broadcast updates to other browsers, that's going to blow away any editing the other users might be doing. I'm talking with Nate tomorrow about it so hopefully I will have some answers. For right now, it seems real easy if you're just wanting realtime updates for a single user.
Broadcasting a stimilus reflex page to other users seems problematic for a few reasons - dirty state (as you mentioned) and having a page looking exactly the same for 2 different users is probably the exception to the rule (in the same way that full page caching is the exception to the rule).
I'm wondering if you could break it down into a few smaller problems:
1) user A makes SR update
2) persist that update into a temporary storage (redis)
3) let SR update user A's entire page (as usual)
4) broadcast a standard "page_updated" event to user B
5) user B's page should do an SR update (based on receiving "page_updated" event)
6) in your reflex action, merge user B's data with user A's data in redis
7) SR will update user B's entire page
There are a few questions/risks with this approach:
1) should all of user A's SR updates be broadcast (even one's w/ errors) or just the ones where user A actually hits save and are actually persisted to the production DB?
2) how do you do the "merge" step in step 6??? will a simple approach work? is it possible to record each SR update (similar to a redux action) so they can be "replayed"? CRDT (blah!)?
3) if there are many user B's, step 5 could make a herd of network requests
Now that I've typed all of that, this approach seems like very very difficult (and this type of conflict resolution is not even something react/redux can solve out of the box).
A simpler approach would be: SR for user A and cable ready for user B. I can imagine 2 flavors of this:
A) If a new piece of data was added (to a list or something) use cable ready to add that entry to user B's list.
B) If data was edited in some dirty way, use cable ready to add a "This page has been updated. Click here to refresh" link to user B's page and let them decide what todo.
Really curious where you end up here.
dev experience looks amazing! looks like the library already throttles/debounces event-generating monsters like mouse move and scrolling, which was my primary concern as soon as I saw you listen to the change event. It also looks like it does DOM diffing and permanent elements and partial DOM updates too!
The only concern i have is if the server can handle the increase in request frequency. server-side performance will be a topic sooner when using stimulus reflex. The form validation example you used seemed to take longer than i expected to appear in the page.
So how would this work if you have multiple fields on your form? Would you have to send them all to the server to persist the state? Or does it "remember" that other fields weren't submitted on the reflex? I'm guessing it doesn't, since it re renders the whole view. So would you have to bind all the values on the form to a target in a stimulus controller and send all of them?
Hi Chris! Excelent video, how can I prevent SR broadcast to all current connections? Is there a workaround for just stream to the same connection that trigger the reflex?
Chris, from what you mentioned in the video about stimulus_reflex, it would re-run an #index action (original page) after a reflex is executed. Wouldn't this be executing a lot of extra DB queries and thus using a lot more memory on servers?
I'm building something similar to a calendar app that displays a variety of events, and when I create a new event, I just need to insert that 1 record onto the page. If I re-ran the entire #index page, that would result in at least 5+ extra queries in most production applications (retrieve current_user, retrieve any user-specific items, query the #index action and possibly any secondary lookups, etc). From my experience the DB is the slowest part of most Rails apps, followed by the view rendering.
My approach currently is to use custom js.erb files with partials (and now view_components from Github) to dynamically update or insert my new events onto the calendar day. This means I only run the minimum DB queries necessary to insert the new record into the DB, and then spit back a little JS to the page that dynamically updates itself.
If the #index pages have a decent amount of content and thus would run several DB queries, is there really a benefit to stimulus_reflex since it automatically re-renders pages?
I can see cable_ready being useful, as it provides a nicer websocket interface to dynamically updating select portions of the page, and thus minimizing unnecessary DB queries.
BTW, I'd love to see some videos on Github's view_components, and get your thoughts on them! I started using them in a few places and I do like the ability to quickly test my views without having to load the entire app via system tests.
Dan, you're correct. If you trigger a reflex, it's just like refreshing the page. That's why I typically wouldn't use Reflex for situations like that where you need to be more efficient. That said, fragment caching can help considerably there. You just have to be careful with what you're doing.
That said, I think Stimulus Reflex killer for just getting something working quick and dirty as a prototype.