3 ms·
The new Turbo 8 allows you to just re-render your page, and using DOM morphing, it will just figure out which divs to update.
by aantix 3y ago
The new Turbo 8 allows you to just re-render your page, and using DOM morphing, it will just figure out which divs to update.
- nickjj 3y agoYep this is really good stuff. The only concern I have is around making things more efficient server side. For example if you have an expensive DB query that's not really cacheable, you can use streams and frames to only have that query execute once on the first page load but then you can navigate between pages that only load in a different frame. A good example is something like a video course platform with a video frame, table of contents area and another frame below the video to load specific things like questions, references, show notes, etc.. As you click links in the table of contents, it loads new content in the video frame but the questions wouldn't change and you also don't need to re-render the table of contents either. You get to skip querying and rendering views for all of those expensive things. With Turbo 8, if you used the new approach you would be rendering non-cacheable very expensive queries and views on every page transition. I want to use Turbo 8's features so much but for the biggest and most complex aspect of my app I don't realistically see how I can. The bookkeeping pain on manually updating 5+ areas of the page and writing a bunch of stream hooks which is multiplied as you add more actions is real though. I'm hoping as Turbo 8 gets more mature new patterns will emerge to let us get the best of both worlds (performance and complexity compression).
- jrsj 3y agoThis scenario does seem like something that would be cacheable to me though. Really its a matter of where you're doing the caching -- on the server, or in the client. It's easier to manage cache invalidation (and state in general) on the server so that seems like the preferable option to me for most things. In the context of Rails specifically, something like Solid Cache helps a lot with this too. There are other similar approaches for other languages/databases as well, although most implementations are based on Postgres instead of MySQL. If the specificity & complexity of the query is the barrier to caching, it's also possible that breaking the query up a bit could still net better performance if it makes it easier to cache.
- nickjj 3y ago> This scenario does seem like something that would be cacheable to me though The table of contents has a course with sections, lessons and downloads / videos with sums of video lengths that roll up to each section and back to the whole course. It rarely changes but the monkey wrench is there's a checkbox next to each lesson where a user can toggle a lesson as being complete so now it's really personalized for each user with a model storing this state. I didn't want to save this client side in local storage in case they watch things on multiple devices. Having a separate cache for each user seemed like it would be a big mess, especially since these "lesson completions" move very fast in the sense that a user can toggle a handful of them per session. This table is also pretty big. Imagine having a 200 lesson course but you have 10,000 people who took it. Now we're at 2 million rows. Russian doll caching seemed pretty dangerous here, I'd have to have touch: true on like 5 cascading models where editing 1 thing would bust components of the cache for everyone. The queries themselves aren't too complicated. It's pretty much 3 queries with "includes" being used at times to avoid N+1 queries. It's getting the course, then looping over its sections and then looping over its lessons and in that lesson loop it gets any downloads. Then there's the lesson completion state for the current user too to see if it should be checked or not. It doesn't seem very friendly to being cached. I really wanted to avoid having a single cache for the whole TOC and making a separate ajax request to load in the user's lesson completions after the page has loaded. The UI gets jittery with the checkboxes being populated afterwards. This also opens a few cans of worms. Even if this were to happen in the end with Turbo 8, I'd still have to query the per user lesson completions + all of the resources (questions or show notes, etc.) presented under the video on every page transition.
- porker 3y agoOther dom morphing setups have the concept of "ignore this sub-tree" which means that on first load you can render the ToC and checkboxes for the user, but then on the AJAX requests from Turbo omit that section of the page entirely. This lets you cache and share them whilst when the user refreshes the page they get the latest ToC. It adds complexity but then if you need caching, what doesn't?
- 3y ago
- radanskoric 3y agoAuthor here. Yes! Turbo 8 changes are very exciting. It hasn't been released yet but it was merged in main and I was trying it out today. I plan dig more into it and write a breakdown. I'm really interested in how it's exactly working to see what corner cases we need to watch out for. As is usual with "magical" features they're great until you run into a corner case. Probably the best way to think about morphing is as something that gets you up and running really quickly. Then as your app matures you can replace high traffic pages with turbo frames and streams or something else. In a typical app, even when it's mature you might find that 80% of the pages are low enough on the performance requiremetns that you can just morphing and then use the development time savings to really optimise the other 20%.