4 ms·
Turbo: The speed of a SPA without writing JavaScript
- sonicrocketman 5y agoI’ve been casually following turbolinks (now Turbo) for a while now, and I intend on using it in a future project. Is anyone out there using turbo? Got any suggestions or tips?
- titusjohnson 5y agoI've been wrangling Turbolinks-based frontends for many years now. Lots of straight HTML, lots of usage of MVVM frameworks (React & friends) for "rich widgets" (Turbolinks load events and a simple data-attribute markup schema makes it pretty easy to mount whatever, wherever). The biggest trick is to remember that with a server-side rendered application is that _your application is the server stack_. What you ship to the user is just an interface. State stays with the Application, just render representation of the state to the client. IE: Prefer rendering HTML all the time. Turbo offers some exciting new patterns for rendering partial page HTML and shipping that to the client automatically, in the past I've done this by adding a specific content type of 'html/partial' and writing generic Javascript that makes a request and replaces its components content with the response. I'm not sure how Turbo handles this, but one gotcha I've had to work around is making sure you deconstruct any JS state before you allow Turbolinks to complete page navigation. Because Turoblinks caches a copy of the "last page" DOM in memory as the user navigates, when the user uses the Back button Turbolinks can restore the cached page and make a request for a new copy of that page, and then do a replace with the fresh content. A little CSS makes this cached page look appropriate (ie: this is cached content, fresh is coming in a minute), but the gotcha comes with any DOM manipulation that any JS libraries may have performed. A good example is a typeahead or time picker. Often times basic DOM is shipped to the client, like an input client and search button, and JS binds to that element on load and replaces it with a rich widget. When you swap pages you have to remember to breakdown that rich widget and remove the DOM it added. Otherwise you can see odd behavior like the user hitting Back, seeing a Rich search widget, then a 2nd search widget shows up (depending on how you have your bindings set), then the remote content is loaded and wipes away what the user is seeing. Basically if you make a mess, clean it up. Keep that in mind page by page, component by component, and you'll be fine. Now for a complete reversal. Turbolinks offers a `keep` directive, you can tag DOM and if the tagged DOM exists in any new pages, Turbolinks will "port over" your old DOM into the new page. I abused this a few years back to build a WebRTC phone calling site. I "kept" the DOM that displayed the status of the current phone call. Because Turbolinks means I can keep a persistent JS process through a user session, effectively my users could make a WebRTC phone call and still navigate through our entire server-side rendered CRM app while maintaining the phone call. Very very handy. I'm excited to try out Turbo.
- sharps_xp 5y agoI've always been hesitant with a introducing a websocket server into my rails application. If the websocket server goes down, you'll still be able to render the SSR-ed shell via the web server. Aren't we just introducing the data consistency problems into every HTML page that uses Turbo. Rails has celebrated its monolithic approach, but i just don't want to deal with websocket problems when what I want is truly a one person framework.
- deleted 5y ago[deleted]
- jaredcwhite 5y agoTurbo isn't websockets. There's a specific Rails integration whereby you can broadcast a Turbo Stream over websockets, but that's 100% optional. You can use Turbo Streams (and Frames and Drive) over pure request/response HTTP lifecycles. I use Turbo on static sites!
- sharps_xp 5y agowow in that case, this is huge for me… i’m currently architecting a rails app to have global users. turbo with http seems perfect to save bandwidth and fine tuned caching configurations… i might have to look at how/when the response is stripped from the frames. TIL
- fayten 5y agoA similar alternative that does not rely on web sockets is https://htmx.org https://htmx.org. I have greatly enjoyed using it with some simpler web frameworks like https://javalin.io https://javalin.io to do some prototyping and smaller projects. I'm sure if someone made a plug and play UI library like material UI for Angular on top of htmx you could absolutely fly through MVPs.